【问题标题】:Linked list - Inserting in middle, linking new node链表 - 插入中间,链接新节点
【发布时间】:2016-03-30 16:57:27
【问题描述】:

查看底部的最后一个函数 i_at()。

#include <stdio.h>
#include <stdlib.h>
#include <malloc.h>
#define nl printf("\n")
#define pf printf
#define si(a) scanf("%d",&a)
#define sc(a) scanf("%c",&a);
struct node{
    int val;
    struct node *next;
};
struct node *first,*last,*damn,*temp,*prev,*newnode;
void i_beg();
void i_end();
void display();
void del();
void i_at();
struct node *create(int);
main()
{
    int val,i,j; char key;val=1;
    while(val<6 && val>0){
        pf("\n1.Start \t2.End \t3.Display\t4.Delete\t5.Insert\t6.Exit\n------------------------------------------------\n");
        si(val);
        if(val==6)exit(0);
        else{
            switch(val){
                case 1: i_beg(); break;
                case 2: i_end(); break;
                case 3: display();break;
                case 4: del(); break;
                case 5: i_at();break;
                case 6: exit(0);break;
            }
        }
    }
}

struct node * create(int val){
    newnode = (struct node *)malloc(sizeof( struct node));
    if(newnode == NULL)
    {
        pf("Oops! You have gone out of memory\n");
        return 0;
    }
    else
    {
        newnode -> val = val;
        newnode -> next = NULL;
        return newnode;
    }

}
void i_beg(){
    int x;
    //if(first -> val == last -> val && first == NULL) pf("Only one node exists!!!\n ");
    pf("Enter a value to insert\t");
    si(x);  newnode = create(x);
    if(first == last && first == NULL)
    {
        first = last = newnode;
        first -> next = NULL;
        last -> next = NULL;
        pf("\n %d inserted at first\n",x);
    }
    else
    {
        temp = first;
        first = newnode;
        first -> next = temp;
        pf("\n %d inserted at first\n",x);
    }
}
void i_end(){
    int x;
    //if(first -> val == last -> val && first == NULL) pf("Only one node exists!!!\n ");
    pf("Enter a value to insert\t");
    si(x);  newnode = create(x);
    if(first == last && first == NULL)
    {
        first = last = newnode;
        first -> next = NULL;
        last -> next = NULL;
        pf("\n %d inserted at last\n",x);
    }
    else
    {
        last -> next = newnode;
        last = newnode;
        last -> next = NULL;
        pf("\n %d inserted at last\n",x);
    }
}
void display(){
    prev = first;
    while(prev != NULL)
    {
        pf("%d -> ",prev -> val);
        prev  = prev -> next;
    }pf(" NULL");
    nl;
}
void del(){
    pf("Enter the position to delete\t");
    int i,pos;si(pos);
    for(prev = first,i=1 ; i<pos-1 ; prev=prev->next,i++);// not i< pos but i<pos-1
    temp = prev -> next;
    prev -> next =  temp->next;
}
void i_at(){
    pf("Enter the position to add after this position\t");
    int i,pos;si(pos);
    for(prev = first,i=1 ; i<pos ; prev=prev->next,i++);
    pf("Enter a value to insert\t");
    si(i);  newnode = create(i);
    temp = prev;

    // order of these statements is important
    newnode -> next = temp -> next;
    prev -> next = newnode;
    pf("%d inserted after position %d\n",i,pos);
}

如果我把这些行写成

prev -> next = newnode;
newnode -> next = temp -> next;

那么 display() 函数出错了。但是如果我将这两行的顺序颠倒为

newnode -> next = temp -> next;
prev -> next = newnode;

那么代码就可以工作了。只需将新节点链接到链表即可。那么,如果我按照代码所示的那样交换这两行的顺序,为什么代码是错误的?

例如:为了将 b 连接到 a&c,连接 (b->c 先,a->b 第二)OR(a->b 先,b->c 第二) 并不重要。 哪里错了?

【问题讨论】:

  • 因为tempprev都指向同一个对象。
  • 我看到您已将其标记为 c++ 而不是 c。 +1 只选择一个,但是如果您使用的是 c++,为什么您使用 malloc 而不是 new?
  • 对于链表来说,首先在纸上完成所有操作,然后在代码中实现这些操作,通常会有很大帮助。
  • @MartinBonner:从他使用的函数和标头来看,我认为他使用的是 C。

标签: c linked-list nodes


【解决方案1】:

当你这样做时:

temp = prev;

您没有复制结构,您只是将名称 prev 与名称 temp 起别名,因为两者都是 指针

所以当你这样做时:

prev -> next = newnode;
newnode -> next = temp -> next;

您正在更改prevtemp 的字段next 的值,第二个语句不正确。

在其他情况下,更新顺序是正确的。

【讨论】:

  • 如果可以复制结构体,那么,我的代码在这两种方式下都正确吗?是否有任何方法可以复制结构体对象。 如果 temp 是 prev 的副本
  • 可以复制 C 中的结构,只需将其分配给另一个结构,但请注意 tempprev 都是两个 指针 i> 到一个结构,而不是结构本身。
  • 最后,还要注意,在这种情况下,管理这种插入的常用方法就像在第二种(正确)情况下一样,不分配新结构并在其中复制旧 val 并更新指针。
  • 是的,你是对的。我们可以通过将结构分配给另一个结构来进行深度复制。在这里,temp = prev 对同一引用进行了浅拷贝。
【解决方案2】:

tempprev 具有相同的值,并且指向相同的对象。因此,这些行可以写成:

newnode -> next = prev -> next;
prev -> next = newnode;

prev -> next = newnode;
newnode -> next = prev -> next;

显然只有其中一个会起作用。

顺便说一句,如果您在每个函数中根据需要声明局部变量,从长远来看,您会发现代码更易于阅读。感兴趣的函数中的任何变量都不需要是全局变量,这使得推理大型程序变得更加困难。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2012-10-27
    • 2018-07-28
    • 2019-04-26
    • 2013-02-06
    • 1970-01-01
    • 2020-02-18
    相关资源
    最近更新 更多