数据结构实现链表的反转

#include <stdio.h>
#include <stdlib.h>
#include <malloc.h>

typedef struct ListNode{
    int data;
    struct ListNode *next;
}inversList;

/*这个函数实现创建链表*/
inversList *createList()
{
    inversList *head=NULL,*a=NULL,*b=NULL;   //定义了指针之后最好清空,以免野指针的出现,
                                             //比如这里的head如果不设置为null的话,下面的oldList==NULL就会导致系统提示调试错误。。。
    while(1)
    {
        if(NULL==(b=malloc(sizeof(inversList))))
        {
            printf("内存申请失败");
            exit(1);
        }                                    //为指针b分配内存空间
        
        printf("输入一个数:");
        scanf("%d",b);                        //输入数存入b指向的内存空间

        if(0==b->data) break;                //直到输入0时,循环结束输入节点
        
        b->next=NULL;                        //将b的next域设置为空,防止野指针出现
        
        if(NULL==a)
        {
            a=b;
            head=a;
        }
        else
        {
            a->next=b;
            a=b;
        }
    }
    return head;
}

/*这个函数实现链表的反转*/
inversList *invert(inversList *next,inversList *prior)
{
    inversList *head=next;
    if(NULL!=next->next)
    {
        head=invert(next->next,next);
    }
    next->next=prior;
    return head;
}

int main(void){
    
    inversList *head,*oldList,*newList;
    printf("------------下面开始创建链表:---------\n");
    
    head=createList();     //这里开始创建链表。。。并定义一个指针oldList指向链表的头节点head,以便于下面链表的输出表示。
    oldList=head;  
    
    if(oldList==NULL) 
        exit(1);        //要先判断,在执行。判断链表是不是为空,如果是就直接退出程序,否则继续执行。。。
    
    else
    {
        printf("The origin of the List is:");
        
        while(oldList!=NULL)
        {
            printf("%d",oldList->data);
            oldList=oldList->next;
        }

        newList=invert(head,NULL);  //定义一个newList指针,指向反转后链表的头节点
        printf("\nThe result of the List is:");
        
        while(newList)
        {
            printf("%d",newList->data);
            newList=newList->next;
        }
        printf("\n");
    }
    free(oldList);           //指针用完后一定要释放归还给系统,以免野指针出现。。。
    free(newList);
    return 0;
}

    /*
        总结一下创建一个链表的几个步骤:

        1 – 创建链表前,首先要知道链表里的节点中,保存的数据都有哪些,因此我们要先声明节点的结构体数据类型;
        2 – 为了链表的操作,我们肯定要创建工具指针,因为它们会帮助我们始终指向我们想要指向的地方;
        3 – 申请空间后一定要验证空间的可用性;
        4 – 录入数据后,要判断数据的录入是否具有延续性,还是一次性;
        5 – 录入数据完毕后,切记要让最后一个节点指向NULL;
        6 – 用完链表后,记得有malloc,就要有free;
        7 – 回收工具指针;
        8 – 返回成功代码。

    */

此程序使用非循环的方式完成链表的反转,利用递归方法实现,完美通过运行,面试可能会用到,有兴趣的看看。。。。。。

//不带头结点的链表___链表反转---递归实现
Node *reverseList_isHead(Node *head)
{
    if(NULL==head||NULL==head->next)
        return ;
    Node *p=reverseList_isHead(head->next);
    head->next->next=head;
    head->next=NULL;
    return p;
}
//不带头结点的链表___链表反转---非递归实现算法
Node *reverseList_isHead(Node *head)
{
    if(NULL==head||head->next==NULL)
        return ;
    Node *p=head->next,
         *q;
    head->next=NULL;
    while(p!=NULL);
    {
        q=p->next;
        p->next=head;
        head=p;
        p=q;
    }
    return head;
}


//带头结点的链表___链表的反转---非递归实现
Node * reverseList_noHead(Node *head)
{
    if(NULL==head||NULL==head->next)
        return;

    Node *p,*q,*t;
    p=head->next;
    q=p->next;
    while(NULL!=q)
    {
        t=q->next;
        q->next=p;
        p=q;
        q=t;
    }
    head->next->next=NULL;
    head->next=p;
    return head;
}

原文地址:https://www.cnblogs.com/foundwant/p/2710162.html