链表学习
围绕逆序链表对链表进行一些输出实验
1. 创建一个只有6个结点的链表,各结点值依次为0 1 2 3 4 5
(借用创建循环链表的方法,感觉直接创建不好控制,主要是前面的结点依赖后面的结点)
1 //创建链表开始 2 int i = 0; 3 link x; 4 link t = (link)malloc(sizeof *t); x = t; 5 t->item = 0; 6 t->next = t; 7 while (++i < 6){ 8 x = (x->next = (link)malloc(sizeof *x)); 9 x->item = i; 10 x->next = t; 11 } 12 x->next = NULL; //此句去掉则为循环链表 13 //创建链表结束
2. 各种打印链表
//0. 直接打印链表 print(t,"0. 直接打印链表"); //1.测试打印情况1 link a = t->next; a = NULL; print(t, "1.测试打印情况1"); //2.测试打印情况2 link b = t; link d = t->next; b->next = NULL; print(t, "2.测试打印情况2"); //3.测试打印情3 link c = t; c->next = NULL; t->next = d; print(t, "3.测试打印情3"); //4. 逆序不改变原始链表打印 link p = copyAndReverse(t); print(t, "4. 逆序不改变原始链表打印"); print(p);
输出结果为
******0. 直接打印链表****** 0 1 2 3 4 5 ******1.测试打印情况1****** 0 1 2 3 4 5 ******2.测试打印情况2****** 0 ******3.测试打印情3****** 0 1 2 3 4 5 ******4. 逆序不改变原始链表打印****** 0 1 2 3 4 5 5 4 3 2 1 0
结合2,3 来看,简单的破坏某个结点值,只要有备份(在2中,由语句link d = t->next;完成备份),原始链表很容易恢复
逆序不改变原始链表方法也很简单,对每个原始结点分别创建对应的新结点
link copyAndReverse(link head){ link y = head, r = NULL; while (y != NULL){ link temp = (link)malloc(sizeof *temp); temp->item = y->item; temp->next = r; r = temp; y = y->next; } return r; }
比较奇怪的在后面,逆序破坏原始链表后,想通过简单的方法恢复出现奇怪现象
破坏性的逆序函数为
link reverse(link head){ link y = head, r = NULL; link t; while (y != NULL){ t = y->next; y->next = r; r = y; y = t; } return r; }
测试代码
//5. 逆序改变原始链表打印 link e = t->next; link q = reverse(t); print(t, "5. 逆序改变原始链表打印"); print(q); //6. 尝试恢复原始链表打印 t->next = e; //print(t, "6. 尝试恢复原始链表打印"); return 0;
输出结果:
******5. 逆序改变原始链表打印****** 0 5 4 3 2 1 0
******6. 尝试恢复原始链表打印******
0
1
0
1
...无限循环
仿照测试3中进行尝试恢复竟然出现无限循环!!!
跟踪调试记录如下
可以看到,逆序完之后,原来的头结点t 只剩下0 了.
恢复不了可以理解,链表顺序被完全打乱之后,一个结点变量不可能记录链表的完整顺序,它只记录当前结点的信息,对后面结点的具体信息其实是完全不知道的,.
可是再往下执行,尼玛的循环怎么出现了
难道是因为
e = t->next;
t->next = e;
就会出现循环怪圈???
完整程序
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
#include<iostream> #include<string> #include<vector> using std::cin; using std::cout; using std::endl; using std::string; typedef struct node* link; struct node{ int item; link next; }; void print(link head, string index){ cout << "******" << index << "******"<<endl; while (head != NULL){ cout << head->item << endl; head = head->next; } cout << endl; } void print(link head){ while (head != NULL){ cout << head->item << endl; head = head->next; } cout << endl; } link reverse(link head){ link y = head, r = NULL; link t; while (y != NULL){ t = y->next; y->next = r; r = y; y = t; } return r; } link copyAndReverse(link head){ link y = head, r = NULL; while (y != NULL){ link temp = (link)malloc(sizeof *temp); temp->item = y->item; temp->next = r; r = temp; y = y->next; } return r; } int main() { //创建链表开始 int i = 0; link t = (link)malloc(sizeof *t), x = t; t->item = 0; t->next = t; while (++i < 6){ x = (x->next = (link)malloc(sizeof *x)); x->item = i; x->next = t; } x->next = NULL; //此句却掉为循环链表 //创建链表结束 //0. 直接打印链表 print(t,"0. 直接打印链表"); //1.测试打印情况1 link a = t->next; a = NULL; print(t, "1.测试打印情况1"); //2.测试打印情况2 link b = t; link d = t->next; b->next = NULL; print(t, "2.测试打印情况2"); //3.测试打印情3 link c = t; c->next = NULL; t->next = d; print(t, "3.测试打印情3"); //4. 逆序不改变原始链表打印 link p = copyAndReverse(t); print(t, "4. 逆序不改变原始链表打印"); print(p); //5. 逆序改变原始链表打印 link e = t->next; link q = reverse(t); print(t, "5. 逆序改变原始链表打印"); print(q); //6. 尝试恢复原始链表打印 t->next = e; //print(t, "6. 尝试恢复原始链表打印"); return 0; }