C:单链表反转(循环)

来源:互联网 发布:php表单提交 编辑:程序博客网 时间:2024/05/16 11:02

* 昨天老师讲了单链表的反转,听的时候挺简单的,结果晚上回到寝室开始写代码就没那么简单了,最后不得已睡了觉,今天中午回来,重新理了一下思路,终于写出来了*

* 现在我们有一个已经建好的链表*
这里写图片描述

* 我们把它反转且不允许申请新的空间,应该怎么办?应该从第二个结点开始,每个都插入到头指针(第0个结点)之后,这样循环下来,就反转了,然后将反转前第一个结点的自引用结构(*next)置空即可。请看图(虚线代表要执行的操作)*
这里写图片描述
这里写图片描述

* 其实就是一个循环插队的操作,看起来很简单,但是实现起来又是另一回事。从图里分析,我们需要知道第一个结点的地址,要插入的结点的地址,下一个要插入的结点的位置,上次插入的结点的位置。上次插入的结点的地址就存在头指针中,不需要新建变量处理。其余的三个我们依次分别用*p,*q和*r三个变量表示。那么我们修改一下上面的图,就应该是这样的*
这里写图片描述

就变成了这样,有了这些分析,我们就开始写代码了,程序功能,输入十进制整数,每个以回车结束,输入-1代表停止输入,之后会输出最初的链表和反转的链表

#include <stdio.h>#include <stdlib.h>#include <Windows.h>typedef struct Node{    int data;    struct Node *next;}node;node* Build(node *h,int x)//单链表建立递归算法{    node *p;    int dt;    p = (node*)malloc(sizeof(node));    h->next = p;    h->data = x;    scanf_s("%d", &dt);    if (dt != -1)    {        p->next = Build(p, dt);//递归开始        return p;    }    else        return NULL;//递归终止}void Swap(node *h)//反转函数{    node *p, *q, *r;    p = h->next;    q = p->next;    p->next = NULL;//第一个结点断开    while (q != NULL)    {        r = q->next;        q->next = h->next;//将要插入的结点与尾结点相连        h->next = q;//让头结点与将要插入的结点相连        q = r;//指向下一个要插入的结点    }}int main(){    node *h, *p, *q;    int x;    scanf_s("%d", &x);    h = (node*)malloc(sizeof(node));    p = (node*)malloc(sizeof(node));    h->next = p;    Build(p, x);    while (p != NULL)    {        q = p;        printf(" >%d", p->data);        p = p->next;        //free(q);    }    printf("\n");    Swap(h);    p = h->next;    while (p != NULL)    {        q = p;        printf(" >%d", p->data);        p = p->next;        free(q);//空间释放    }    system("pause");}
原创粉丝点击