看图理解单链表的反转
来源:互联网 发布:如何申请淘宝店铺 编辑:程序博客网 时间:2024/05/23 21:15
如何把一个单链表进行反转?
方法1:将单链表储存为数组,然后按照数组的索引逆序进行反转。
方法2:使用3个指针遍历单链表,逐个链接点进行反转。
方法3:从第2个节点到第N个节点,依次逐节点插入到第1个节点(head节点)之后,最后将第一个节点挪到新表的表尾。
方法4: 递归(相信我们都熟悉的一点是,对于树的大部分问题,基本可以考虑用递归来解决。但是我们不太熟悉的一点是,对于单链表的一些问题,也可以使用递归。可以认为单链表是一颗永远只有左(右)子树的树,因此可以考虑用递归来解决。或者说,因为单链表本身的结构也有自相似的特点,所以可以考虑用递归来解决)
方法1:
浪费空间。
方法2:
使用p和q两个指针配合工作,使得两个节点间的指向反向,同时用r记录剩下的链表。
p = head;
q = head->next;
head->next = NULL;
现在进入循环体,这是第一次循环。
r = q->next;
q->next = p;
p = q;
q =r;
第二次循环。
r = q->next
q->next = p;
p = q;
q = r
第三次循环。。。。。
具体代码如下
- ActList* ReverseList2(ActList* head)
- {
-
- if(NULL==head|| NULL==head->next) return head;
- ActList* p;
- ActList* q;
- ActList* r;
- p = head;
- q = head->next;
- head->next = NULL;
- while(q){
- r = q->next;
- q->next = p;
- p = q;
- q = r;
- }
- head=p;
- return head;
- }
updated 2014-01-24,重新非IDE环境写了一遍
如果觉得上面的先成环再断环的过程不太好理解,那么可以考虑下面这个办法,增加一个中间变量,使用三个变量来实现。
- struct ListNode{
- int val;
- ListNode* next;
- ListNode(int a):val(a),next(NULL){}
- };
- ListNode* reverseLinkedList3(ListNode* head){
- if(head==NULL||head->next==NULL)
- return head;
- ListNode* p=head;
- ListNode* r=head->next;
- ListNode* m=NULL;
- ListNode* tail=head->next;
- while(r!=NULL){
- m=r;
- r=r->next;
- m->next=p->next;
- p->next=m;
-
-
-
-
- }
- head=p->next;
- tail->next=p;
- p->next=NULL;
- tail=p;
- return head;
- }
方法3
还是先看图,
从图上观察,方法是:对于一条链表,从第2个节点到第N个节点,依次逐节点插入到第1个节点(head节点)之后,(N-1)次这样的操作结束之后将第1个节点挪到新表的表尾即可。
代码如下:
- ActList* ReverseList3(ActList* head)
- {
- ActList* p;
- ActList* q;
- p=head->next;
- while(p->next!=NULL){
- q=p->next;
- p->next=q->next;
- q->next=head->next;
- head->next=q;
- }
-
- p->next=head;
- head=p->next->next;
- p->next->next=NULL;
- return head;
- }
附:
完整的链表创建,显示,反转代码:
方法4: 递归
updated: 2014-01-24
因为发现大部分问题都可以从递归角度想想,所以这道题目也从递归角度想了想。
现在需要把A->B->C->D进行反转,
可以先假设B->C->D已经反转好,已经成为了D->C->B,那么接下来要做的事情就是将D->C->B看成一个整体,让这个整体的next指向A,所以问题转化了反转B->C->D。那么,
可以先假设C->D已经反转好,已经成为了D->C,那么接下来要做的事情就是将D->C看成一个整体,让这个整体的next指向B,所以问题转化了反转C->D。那么,
可以先假设D(其实是D->NULL)已经反转好,已经成为了D(其实是head->D),那么接下来要做的事情就是将D(其实是head->D)看成一个整体,让这个整体的next指向C,所以问题转化了反转D。
上面这个过程就是递归的过程,这其中最麻烦的问题是,如果保留新链表的head指针呢?想到了两个办法。
-
- struct ListNode{
- int val;
- ListNode* next;
- ListNode(int a):val(a),next(NULL){}
- };
-
- class Solution{
- ListNode* reverseLinkedList4(ListNode* head){
- if(head==NULL)
- return NULL;
- if(head->next==NULL){
- m_phead=head;
- return head;
- }
- ListNode* new_tail=reverseLinkedList4(head->next);
- new_tail->next=head;
- head->next=NULL;
- return head;
- }
- ListNode* m_phead=NULL;
- };
第二个办法是,增加一个引用型参数 new_head,它用来保存新链表的头指针。- struct ListNode{
- int val;
- ListNode* next;
- ListNode(int a):val(a),next(NULL){}
- };
-
- class Solution{
- ListNode* reverseLinkedList5(ListNode* head, ListNode* & new_head){
- if(head==NULL)
- return NULL;
- if(head->next==NULL){
- new_head=head;
- return head;
- }
- ListNode* new_tail=reverseLinkedList5(head->next,new_head);
- new_tail->next=head;
- head->next=NULL;
- return head;
- }
- };
http://blog.csdn.net/feliciafay/article/details/6841115
http://blog.csdn.net/autumn20080101/article/details/7607148
//error pPrv->next
int reverse_linklist(LinkNode *head)
{
#if 1
printf("fun 00\n");
LinkNode *pPrv = head;
LinkNode *Cur = head->next;
LinkNode *pNext = NULL;
head->next = NULL;
while( Cur )
{
pNext = Cur->next;
Cur->next = pPrv->next;
pPrv->next = Cur;
Cur = pNext;
}
return 0;
#include <stdio.h>#include <stdlib.h>typedef int DataType; typedef struct node { DataType data; struct node *next;}LinkNode; LinkNode *create_empty_linklist(){ LinkNode *head = NULL; head = (LinkNode *)malloc(sizeof(LinkNode)); head->next = NULL; return head;} int is_empty_linklist(LinkNode *head){ return head->next == NULL;} int insert_head_linklist(LinkNode *head,DataType data){ LinkNode *temp = NULL; temp = (LinkNode *)malloc(sizeof(LinkNode)); temp->data = data; temp->next = head->next; head->next = temp; return 0;} int insert_tail_linklist(LinkNode *head,DataType data){ LinkNode *temp = NULL; LinkNode *p = head; temp = (LinkNode *)malloc(sizeof(LinkNode)); temp->data = data; //找到尾结点 while(p->next) { p = p->next; } //temp->next = NULL; temp->next = p->next; p->next = temp; return 0;} int insert_order_linklist(LinkNode *head,DataType data){ LinkNode *temp = NULL; LinkNode *p = head; temp = (LinkNode *)malloc(sizeof(LinkNode)); temp->data = data;#if 0 while(p->next) { if(p->next->data > data) { break; } p = p->next; }#endif /*while(p->next != NULL && p->next->data < data)*/ while(p->next && p->next->data < data) { p = p->next; } temp->next = p->next; p->next = temp; return 0;}int delete_assign_node(LinkNode *head,DataType data){ LinkNode *temp = NULL; LinkNode *p = head; while(p->next && p->next->data != data) { p = p->next; } if(p->next == NULL) { return -1; } temp = p->next; p->next = p->next->next; free(temp); return 0;} int print_linklist(LinkNode *head){ LinkNode *p = head->next; while(p) { printf("%d ",p->data); p = p->next; } putchar('\n'); return 0;}int order_data(LinkNode *head){ LinkNode *sa; LinkNode *sb; int t ; for(sa = head->next; sa != NULL ;sa = sa->next) { for(sb=sa->next;sb != NULL;sb = sb->next) { if(sa->data > sb->data) { t = sa->data; sa->data= sb->data; sb->data = t; } } } return 0;} int reverse_linklist(LinkNode *head){#if 1printf("fun 00\n");LinkNode *pPrv = head;LinkNode *Cur = head->next;LinkNode *pNext = NULL;head->next = NULL;while( Cur ){pNext = Cur->next;Cur->next = head->next;head->next = Cur;Cur = pNext;}return 0;#endif#if 0 LinkNode *p = head,*q = NULL; if(p->next == NULL || p->next->next == NULL) { return -1; } q = p->next->next; p->next->next = NULL; while(q) { p = q->next; q->next = head->next ; head->next = q; q = p; } return 0;#endif} int main(){ LinkNode *head = NULL; int a[] = {1,5,3,4,7,9}; int i = 0; int ret = 0; head = create_empty_linklist(); for(i = 0;i < sizeof(a) / sizeof(a[0]);i++) { /*insert_head_linklist(head,a[i]);*/ /*insert_tail_linklist(head,a[i]);*/ insert_order_linklist(head,a[i]); } print_linklist(head);#if 0 ret = delete_assign_node(head,5); if(ret < 0) { printf("Assign data %d is not exist.\n",5); } print_linklist(head);#endif reverse_linklist(head); #if 0 for(i = 0 ; i < 6 ; i ++) { printf("%d ",a[i]); } #endif print_linklist(head); return 0;}