说明:本文仅供学习交流。转载请标明出处。欢迎转载!
题目:存在一个单链表,头指针为head,实现单链表的反转Node *Reverse(Node *head)。
该算法的求解办法有非常多,如:
方法1:先顺序变量单链表,将结点保存到栈中,在从栈中弹出结点,又一次建立一个新的单链表;
方法2:用《剑指offer》里面给出的算法,用三个指针来实现;
方法3:採用递归实现,是方法2的递归实现形式。
本文主要给出方法2和方法3。在给出详细的代码之前,先要注意几个问题:
(1)假设head为空,该怎样处理?
(2)假设链表为单节点链表,该怎样处理?
(3)怎样防止在反转过程中断链?
(4)反转后head是否更新?
(5)反转后得到的链表最后一个结点是否为null?
考虑完以上问题后,就能够写出正确的代码了。
代码实现例如以下:
<pre name="code" class="cpp">#include<iostream> using namespace std; struct Node { int value; Node* next; Node(int v):value(v){} }; /*创建一个链表,1->2->3->4->5->6->7*/ Node* CreateList()//创建一个单链表 { Node *head; Node *n1=new Node(1); Node *n2=new Node(2); Node *n3=new Node(3); Node *n4=new Node(4); Node *n5=new Node(5); Node *n6=new Node(6); Node *n7=new Node(7); head=n1; n1->next=n2; n2->next=n3; n3->next=n4; n4->next=n5; n5->next=n6; n6->next=n7; n7->next=NULL; return head; } void FreeList(Node *head)//将链表空间释放 { if(head==NULL) { return ; } else { Node *temp=head->next; delete head; head=temp; FreeList(head); } } void VisitList(Node *head)//遍历链表中的元素,用递归的方法遍历 { if(head) { cout<<head->value<<"->"; VisitList(head->next); } else { cout<<"null"<<endl; } } Node *Reverse(Node *head)//反转单链表 { if(!head || !head->next)//假设是空链表或者仅含一个结点的链表 { return head; } Node *p1,*p2,*temp; p1=head; p2=head->next; p1->next=NULL;//这是反正后链表的最后一个结点(即原来的第一个结点) while(p2) { temp=p2->next;//防止段链 p2->next=p1;//反转 //前进 p1=p2; p2=temp; } head=p1; return p1; } Node *Reverse1(Node *head)//用递归法实现 { if(!head || !head->next) { return head; } Node *nextNode=head->next; head->next=NULL; Node *head1=Reverse(nextNode); nextNode->next=head; return head1;//这里是递归过程 } int main() { Node *head=CreateList(); cout<<"原链表输出为:"; VisitList(head); head=Reverse(head); cout<<"反转后的链表为(循环法):";//循环法 VisitList(head); cout<<"再反转链表(递归法):"; head=Reverse1(head);//递归法 VisitList(head); FreeList(head);//释放链表空间 return 0; }
測试结果例如以下:
參考资料-------------《剑指offer》