剑指offer面试题16 反转链表(递归和非递归,主要还是看代码的鲁棒性)

来源:互联网 发布:禁止电脑安装软件 编辑:程序博客网 时间:2024/06/06 03:01
/*这题早就做过了,但是当时看的书上的代码真的很差,比其这本书差的不少。。剑指offer真是我大学看过的最好的书之一了反转链表 需要对链表进行遍历 每次对于遍历到的节点,先记录next,再next指向前一个,然后继续遍历 注意不要把链表弄段还有注意输入 最主要的是输入头节点NULL 的处理 测试数据要想到 只有一个节点怎么办 两个,多个怎么办 输入NULL 怎么办只要自己想到测试数据都过了 代码才可以提交*/#include<iostream>#include<cstdio>using namespace std;struct Node{    int data;    Node * next;};void PrintList(Node * head){    if(head==NULL)    printf("empty List\n");    Node * p=head;    while(p!=NULL)    {        printf("%d ",p->data);        p=p->next;    }    cout<<endl;}Node * ReverseList(Node * head){    Node * pre=NULL;//因为头节点的前一个是空的    Node * p=head;    Node * newhead=NULL;//如果输入空指针 不进入循环 返回newhead 所以赋初值NULL    while(p!=NULL)    {        Node * p_next=p->next;//先记录下一个        if(!p_next)        newhead=p;        p->next=pre;//再把next指向前一个        pre=p;        p=p_next;    }    return newhead;}// 单链表反序的递归算法,这个相对好理解 想起以前看那本CC++程序员面试宝典,也是在那看的//递归算法,太尼馬坑了 那本书我还通透的看完了。那个代码本来就有错 还不好理解,看来选经典好书真的太重要了//这个算法就相对好理解了 一直递归执行这个函数 知道最后一个节点的时候 因为head->next是空了 返回了head//因为是最后一个节点 这个head就是反转后的头节点 在倒数第二个里面newhead就是新的头节点//接下来两句很经典 head->next->next=head 这句话把链表的指针到过来了//这个时候 这个head就是目前链表的末尾 所以next赋值NULL 太经典了 这个算法真好Node * ReverseListRecursively(Node * head)//递归方法 相对好理解{    if(head==NULL || head->next==NULL) return head;    Node * newhead=ReverseListRecursively(head->next);    head->next->next=head;    head->next=NULL;    return newhead;}int main(){    //freopen("/home/gl/in","r",stdin);    int n;    while(scanf("%d",&n)!=EOF)    {        Node * head;        if(!n)        head=NULL;        else        head=new Node();        Node * p=head;        for(int i=0;i<n;++i)        {            scanf("%d",&p->data);            if(i==n-1)            {                p->next=NULL;                break;            }            p->next=new Node();            p=p->next;        }        PrintList(head);       // Node * newhead = ReverseList(head);        Node * newhead=ReverseListRecursively(head);        PrintList(newhead);    }    return 0;}

原创粉丝点击