C:单链表反转(循环)

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

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

* 我们把它反转且不允许申请新的空间,应该怎么办?应该从第二个结点开始,每个都插入到头指针(第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");
}

猜你喜欢

转载自blog.csdn.net/kongming07/article/details/78811850