【问题标题】:Linked List element insertion at nth location在第 n 个位置插入链表元素
【发布时间】:2016-12-31 12:25:09
【问题描述】:

我正在尝试在 C 中实现链表,并且我有两个不同的函数,它们应该在开头和第 n 个位置插入元素。当我的程序进入它开始执行要在第 n 个位置插入的函数的部分时,它会崩溃。有人可以指出我的错误。此外,编译器倾向于跳过最后一个 scanf 语句(在 cmets 中标记)。

/****************************************************************
*Date: 12/30/2016
*This program adds an element to the beginning  and nth position
*of a linked list and then displays the elements in the list
*****************************************************************/


#include <stdio.h>
#include <stdlib.h>
#include <malloc.h>



struct node
{
    int data;//Refers to the data part of the linked list
    struct node* next;//Refers to the pointer which points to the next element
};


/*************************************************************************************
Description   : This function is used to print the elements in the linked list
Input         : Pointer to the beginning of the linked list
Output        : N/A
*************************************************************************************/


void PrintElements(struct node *start)
{
    if(start==NULL)//If the list is empty
        printf("List is empty");
    else
    {
        while(start!=NULL)
        {
            printf("%d ",start->data);
            start=start->next;
        }
    }
}

/*************************************************************************************
Description   : This function is used to insert elements in the beginning of the
                linked list
Input         : Element to be inserted
Output        : N/A
*************************************************************************************/

struct node* InsertElementInTheBeginning(struct node *start, int x)
{
    struct node *new_node=(struct node*)malloc(sizeof(struct node));
    if(new_node==NULL)
    {
        printf("Memory allocation failed");
        return start;
    }
    new_node->data=x;
    new_node->next=start;
    start=new_node;
    return new_node;

}

/*************************************************************************************
Description   : This function is used to insert elements in the nth position of the
                linked list
Input         : Element and position to be inserted, pointer to beginning of linked
                list
Output        : N/A
*************************************************************************************/

struct node* InsertElementAtN(struct node *start,int x, int n)//Here the starting position for the linked list is assumed to be 1
{
    int i;
    struct node* new_node=(struct node*)malloc(sizeof(struct node));
    if(new_node==NULL)
    {
        printf("Memory allocation failed");
        return start;
    }
    new_node->data=x;
    new_node->next=NULL;
    if(n==1)
    {
        new_node->next=start;
        start=new_node;
        return start;
    }
    struct node *ptr;
    ptr=start;
    for(i=0;i<n-2;i++)
    {
        ptr=ptr->next;
    }

    new_node->next=ptr->next;
    ptr->next=new_node;
    return start;
}

int main()
{

    int x, n;
    struct node *HEAD;
    struct node *ptr;
    HEAD=NULL; //Assigning HEAD to null when there are no elements in the list
    ptr=NULL;
    printf("\n\rEnter numbers to be inserted into the list\n Press q to quit\n");
    while(scanf("%d",&x)==1)
    {
        HEAD=InsertElementInTheBeginning(HEAD,x);
        PrintElements(HEAD);
        printf("\n\rEnter numbers to be inserted into the list\n Press q to quit\n");
    }
        printf("\n\rEnter the number and position to be inserted");
        scanf("%d %d",&x,&n);//The compiler always skips this scanf no clue why
        HEAD=InsertElementAtN(HEAD, x, n);
        PrintElements(HEAD);

     //Freeing dynamic memory

    while(HEAD!=NULL)
    {
        ptr=HEAD;
        HEAD=ptr->next;
        free(ptr);

    }

    return 0;
}

【问题讨论】:

  • 跳过最后一条scanf语句因为按q退出需要把输入的q去掉。
  • 试试scanf("q%d %d",&amp;x,&amp;n);scanf("%*[Qq]%d %d",&amp;x,&amp;n);
  • 到底是谁教你把\n\r放在消息的开头?!
  • 考虑永远不要使用scanf()。改为使用fgets() 读取用户输入,然后将字符串处理成int 等。
  • 如果必须使用scanf(),请务必检查函数返回值。代码使用while(scanf("%d",&amp;x)==1) 做到了这一点 - 很好。奇怪的是,scanf("%d %d",&amp;x,&amp;n); 没有代码,这就是问题所在。

标签: c data-structures linked-list


【解决方案1】:

我总是发现这样的东西对我来说更容易理解(我假设你的位置必须是 1 或更多,这与通常的 C 约定的 0 或更多不同):

struct node *insertValueAt(struct node *head, int value, int position) {
    struct node *current;

    if (head == NULL || position == 1)
         return insertBefore(head, value);

    for (current = head; position > 1 && current->next != NULL; position--)
        current = current->next;

    current->next = insertBefore(current->next, value);

    return head;
}

请注意,我使用了名称 insertBefore,但您的 InsertElementAtTheBeginning 也是如此。在现有节点AB 之间插入节点N 的关键是使A-&gt;next 指向从InsertElementAtTheBeginning(B, value) 返回的N

要注意的另一件事是在 NULL 节点之前无条件插入(即在空列表的开头或列表的末尾),无论 position 的值如何,因为您不能插入如果您只有少于 4 个项目,则项目位于位置 10。

【讨论】:

    【解决方案2】:

    在 main() 中的第一个 while 循环之后添加一个 getchar()。解释请查看C: Multiple scanf's, when I enter in a value for one scanf it skips the second scanf

    【讨论】:

      【解决方案3】:

      您应该检查 ptr->next 不为 NULL。

       for(i=0;i<n-2;i++)
       {
          if (ptr->next == NULL) return NULL;
          ptr=ptr->next;
       }
      

      【讨论】:

      • 我确实尝试过进行更改,但它仍然会跳过我在 cmets 中标记的 scanf 语句。即使使用 getchar 代替 scanf 也无济于事。
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2015-09-11
      • 2020-07-25
      • 2020-05-20
      • 1970-01-01
      相关资源
      最近更新 更多