反转链表非递归/递归d

来源:互联网 发布:cms什么意思 编辑:程序博客网 时间:2024/06/05 12:08

题目:

输入一个链表的头结点,反转该链表,并返回反转后链表的头结点。

(a)为链表,(b)为反转后的链表。

假设当前指针为i,则我们需要将i->next=h.此时i和j之间会断裂,因此,我们需要另一个指针j去指示j的位置,同时i->next=h中的h也需要记录,因此,要反转一个链表需要用到3个指针同步向前遍历,基于这个思路,可以轻松写出下面的程序,唯一需要注意的是空指针的情况,越界的情况。


总结:

链表反转可以有3种方式:

1.三指针法,每次调整cur指针,然后pre,cur,post指针同步前移。

2.递归法。

3.可以利用链表头插法的特点,依次取出链表的表头元素,往新链表中做头插法,则可以完成反转,但是如果要求在原址完成,这个办法就不适用了,这个方式本质上还是属于三指针法。

#include<iostream>using namespace std;typedef struct node{int value;node* next;node(int v):value(v),next(NULL){}} NODE;typedef struct List{NODE* head;List():head(NULL){}} LIST;//http://blog.csdn.net/leolinsheng/article/details/9322185//链表尾插入是二叉树迭代法插入的一种特例简化版(code:21-38)void List_Tail_Insert(LIST* L,NODE* Z){NODE* y=NULL;NODE* x=L->head;while(x!=NULL){y=x;x=x->next;}if(y==NULL)L->head=Z;elsey->next=Z;}//扩展:头插入法,需要管理的指针更少(不需要用y)void List_Head_Insert(LIST* L,NODE* Z){if(Z==NULL) return ;Z->next=L->head;L->head=Z;}//解决空指针,解决k太大node* Reserve_List(LIST* L){NODE* Prec=NULL;NODE* Current=L->head;NODE* Next=NULL;while(Current){Next=Current->next;//使Next指向当前指针的下一个,之所为不在循环外初始化,原因是Current可能为NULLCurrent->next=Prec;//旋转指针Prec=Current;//(1)Current=Next;//(2)if(Current==NULL)return Prec;Next=Next->next;//(3)三个指针prec current next前移}return Current;}node* RecReverseList(node *head){if (head==NULL)  return NULL;node* reverse_head ;if(head->next==NULL)return head;//将head->next至末尾的链表反转,则此时head->next已在链表末尾//reverse_head记录的是新链表的表头reverse_head=RecReverseList(head->next);//然后将head->next的next指针指向以前的head指针head->next->next=head;//head的next指针指向NULL,则反转完成了head->next=NULL;return reverse_head;}void main(){int A[]={4,3,1,6,7,8,9,2};int len=sizeof(A)/sizeof(A[0]);LIST* L=new LIST;for(int i=0;i<len;++i){List_Tail_Insert(L,new NODE(A[i]));}NODE* p=L->head;while(p){cout<<p->value<<' ';p=p->next;}L->head=Reserve_List(L);//L->head=RecReverseList(L->head);p=L->head;cout<<endl;while(p){cout<<p->value<<' ';p=p->next;}}


原创粉丝点击