繁体   English   中英

C:从单链接列表中删除节点并将其插入单链接列表2的头部

[英]C: Removing a node from singly-LinkedList1 and inserting it at the head of singly-LinkedList2

我正在做一个模拟操作系统进程调度程序的计算机科学项目。 我有多个单链表 ,需要在它们之间移动节点 我正在尝试编写一个通用函数来实现这一目标,但我认为使用指针的弱点正在阻碍我。

如何实现所需的功能? 到目前为止,我有以下内容:

typedef struct process_list_struct ProcessList;

struct process_list_struct
{
    Process proc;
    ProcessList* next;
};

void change_lists(ProcessList* node, ProcessList* newlist)
{
    ProcessList* temp = NULL;
    debug_printf("change_lists reached\n");
    temp = node;
    if(!node)
    {
        debug_printf("Error: change_lists failed!\n");
        return;
    }
    node = node->next;
    temp->next = newlist;
    newlist = temp;
    return;
}

其结果是奇怪......我最终包含我想移动节点和其他一切失踪(几乎比我想要的东西相反的效果),以及newlist(如测试开始是空的)第一个列表为空。

我已经在单个列表中查找了节点交换的实现,并且看到人们使用双指针 ,但这让我感到困惑。 有人可以告诉我如何在这种情况下应用它们吗? 我尝试使用它们,但它们结合引用结构的指针元素真的令人困惑。

非常感谢帮助!

您将以下四个步骤错误地将节点从一个列表转移到另一个列表:

temp = node
node = node->next;
temp->next = newlist;
newlist = temp;

见下图我用图表显示:

假设您在链表列表1中有节点

    +---+----+----+      +----+----+----+      +---+----+----+
  ->|   zero      |----->|      one     |----->|    two      |--
    +---+----+----+      +----+----+----+      +---+---+-----+
                             ^   ^
                             |   |
                             |  node 
    after temp=node        temp

之后: node = node->next; 事情变得像:

    +---+----+----+      +----+----+----+      +---+----+----+
  ->|   zero      |----->|      one     |----->|    two      |--
    +---+----+----+      +----+----+----+      +---+---+-----+
                             ^                        ^
                             |                        |
                             temp                    node            

temp->next = newlist; 这个 ?

    +---+----+----+      +----+----+----+      +---+----+----+
  ->|   zero      |----->|      one     |      |    two      |--
    +---+----+----+      +----+----+----+      +---+---+-----+
                             ^       |                ^
                             |       |                |
                             temp    |                node     
                                     |
                                     |
                                     |    "head node"
                                     |   +---+----+----+   +---+----+---+
         "This is your list-2"       |-->|   FIVE      |-->|   SIX      |--
                                         +---+---+-----+   +---+----+---+ 
                                          newlist

你的步骤newlist = temp;

                           newlist                    
                            |
                            ▼ "head node"
    +---+----+----+      +----+----+----+      +---+----+----+
  ->|   zero      |----->|      one     |      |    two      |--
    +---+----+----+      +----+----+----+      +---+---+-----+
                             ^       |                ^
                             |       |                |
                             temp    |                node     
                                     |
                                     |    
                                     |   +---+----+----+   +---+----+---+
         "This is your list-2"       |-->|   FIVE      |-->|    SIX     |--
                                         +---+---+-----+   +---+----+---+

这是你做的。 但它不是你想要的?
你将算法从一个列表转移到另一个列表的算法是错误的另外你做了技术错误,你是通过值传递指针(你需要指针指向反映调用函数的变化)

因为你想将节点从一个列表转移到另一个列表,并在一个列表和其他列表的头部传递node指针,你需要传递指针的指针以反映调用函数的变化,因此你的声明在我看来是错误的:

void change_lists(ProcessList* node, ProcessList* newlist)

我认为它应该是:

void change_lists(ProcessList** node, ProcessList** newlist) 

使用此原型将代码写入shift节点。

编辑 :(建议)

代码中的基本问题是在列表1中移位节点( 例如一个 ),而不是将指针更改为前一个节点( 图中的零节点 ),您需要制作

[zero] ---> [two]

@CodeRat在他的列表中犯了类似错误: 在单链表中交换节点

我给了他一个答案,我认为这将有助于您实现代码。

老答案:

我能找到一个错误:而不是

*temp = *node;

你应该写

temp = node;

解决不是价值观

*temp = *node; 是未定义的行为,因为您没有为temp分配内存,您需要在temp中分配地址。 (temp指向NULL)因为你想将节点从一个列表转移到另一个列表,这就是你需要temp = node;

我相信你的原型是错的,它太简单了。

如果不能以某种方式更改哪个节点被视为列表的开头,则无法移动单链表的节点。

否则,如果移动第一个节点会发生什么? 周围的代码将保留指针,但该节点现在逻辑上是移动的目标列表的一部分,并且所有节点都被破坏。

此外,同样适用于目的地列表:如果在移动之前它是空的怎么办?

这段代码中明显错误的一件事是做*temp = *node; temp = NULL 您不能取消引用NULL指针。

此外,如果node属于单链接列表,如果只有指向node的指针,则无法将其从列表中删除。 要删除它,您需要更改指向node ,使其不再指向node ,而是指向NULL或指向节点后面的node 如果您使用的双向链表,你会发现邻居节点到node只给出一个指向node

要从单个链接列表中删除节点,需要其上一个节点。 前一个节点必须链接到下一个节点。

如果该功能可以使用上一个节点,那么很好,但如果没有,则必须从头部开始查看。 因此,头部是必需的。

两个列表的头部都是必需的。 由于删除或添加操作可以更改头指针,因此将它们作为指针指针传递是很自然的。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM