链表插入排序中指针修改为何影响原节点?求原理解析
链表插入排序中指针指向的疑问
我实现了一个对存储单个单词的链表进行插入排序的代码,代码运行正常,但其中一段参考网上的逻辑我无法理解。
Node* insertion_sort(Node* head) { Node* dummy; dummy= malloc(sizeof(Node)); if (dummy == NULL) { printf("Memory allocation error"); } dummy->next = head; Node* last_sorted = head; Node* current = head->next; while (current != NULL) { if(strcmp(last_sorted->word, current->word) <= 0) { // 注:原代码此处遗漏->word,否则是比较指针地址而非字符串 last_sorted = current; } else { Node* prev = dummy; while (strcmp(prev->next->word, current->word) < 0) { prev = prev->next; } last_sorted->next = current->next; current->next = prev->next; prev->next = current; } current = last_sorted->next; } return dummy->next; }
其中prev->next = current;这一行,为什么会改变dummy节点的指向?这两个节点难道不是相互独立的吗?我猜测这和指针的工作机制有关,但我刚接触指针。我已经通过调试器观察到了这个变化,但不明白其中的原因和过程。
问题解答
核心要搞懂指针的本质是存储内存地址的变量:
- 代码中
Node* prev = dummy;这行,并不是创建新的独立节点,而是让prev这个指针变量存储了dummy节点的内存地址——也就是说,prev和dummy指向的是同一块内存空间。 - 当你通过
prev->next修改值时,本质是通过prev找到它指向的内存块(也就是dummy所在的那块内存),然后修改该内存块里的next成员,这个修改自然会同步反映到dummy->next上。
结合代码场景具体拆解:
在else分支中,prev从dummy开始遍历,目的是找到第一个prev->next的单词比current大的位置:
last_sorted->next = current->next;—— 把current从原链表位置“摘”下来current->next = prev->next;—— 让current的next指向prev原来的下一个节点,做好插入前的衔接prev->next = current;——prev此时要么指向dummy,要么指向已排序部分的某个节点,修改它的next为current,就把current插入到了正确的排序位置。如果prev刚好指向dummy,那修改的就是dummy的next,自然会改变dummy的指向。
简单说:prev不是独立节点,它只是dummy的“别名指针”,操作prev的成员就是操作dummy的成员,因为它们指向同一块内存。
内容的提问来源于stack exchange,提问作者tthh
相关产品推荐
相关产品推荐

