链表学习

围绕逆序链表对链表进行一些输出实验

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;

就会出现循环怪圈???

 完整程序

#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;
}
View Code

 

posted @ 2017-09-23 22:12  疾风剑  阅读(387)  评论(0编辑  收藏  举报