k_eckel:http://www.mscenter.edu.cn/blog/k_eckel & http://k-eckel.cnblogs.com
在《单链表操作——交换节点》的代码中,有一个Bug,就是当交换的是链表中相邻的两个节点的时候,程序会Down,原因是在交换节点操作中指针的修改引起的(只需要手工运行下程序就十分清楚了)。因此需要作一点修补,就是判断两个节点是否是相邻节点,再单独处理即可。
总结链表节点交换时候至少需要考虑的情况有(这里不进行必要的参数验证):
1) 链表头节点不参与任何交换;
2) 节点相同就不必进行交换;
3) 节点相邻的时候要特殊处理。
之所以对单链表的节点交换作了较多的描述,是因为单链表的节点交换作是链表排序中
的基本操作,具体将在相应的实现中描述。因此这里给出的交换节点函数传入的直接就是链表和两个节点,如果传入的是节点的关键字,先遍历链表定位就可以了,相关数据结构的定义参见《单链表操作——交换节点》。
修改后的源码为:
void ExchLinkNode(const LinkNode head,const LinkNode node1,const LinkNode node2) { //head不准被交换 LinkNode prenode1 = NULL; //保存待交换节点node1的前一个节点 LinkNode postnode1 = NULL; //保存待交换节点node1的后一个节点 LinkNode prenode2 = NULL; //保存待交换节点node2的前一个节点 LinkNode postnode2 = NULL; //保存待交换节点node2的后一个节点 LinkNode tmp = head; //不得和头节点交换 if (node1 == head) { return ; } else if (node2 == head) { return ; } //自己和自己就不必交换了 if (node1 == node2) { return ; } //节点相邻情况处理 if (node1->_next == node2) { tmp = head; while (tmp->_next != node1) { tmp = tmp->_next; } prenode1 = tmp; postnode2 = node2->_next; prenode1->_next = node2; node2->_next = node1; node1->_next = postnode2; return ; } if (node2->_next == node1) { tmp = head; while (tmp->_next != node1) { tmp = tmp->_next; } prenode2 = tmp; postnode1 = node1->_next; prenode2->_next = node1; node1->_next = node2; node2->_next = postnode1; return ; } tmp = head; while (tmp->_next != node1) { tmp = tmp->_next; } prenode1 = tmp; tmp = head; while (tmp->_next != node2) { tmp = tmp->_next; } prenode2 = tmp; postnode1 = node1->_next; postnode2 = node2->_next; //交换节点 prenode1->_next = node2; node2->_next = postnode1; prenode2->_next = node1; node1->_next = postnode2; } |