单链表的逆置(头插法和就地逆置)

来源:互联网 发布:淘宝时尚韩国女装店铺 编辑:程序博客网 时间:2024/06/05 00:37

今天课间的时候偶然看到了一个面试题:单链表的逆置,看了题解感觉乖乖的,貌似和以前看的版本不搭,于是重新进行了一番探究

单链表的逆置分为两种方法:头插法和就地逆置法,这两种方法虽然都能够达到逆置的效果,但还是有着不小的差别

头插法

这里写图片描述

算法思路:依次取原链表中的每一个节点,将其作为第一个节点插入到新链表中,指针用来指向当前节点,p为空时结束。
核心代码

void reverse(node*head){    node*p;    p=head->next;    head->next=NULL;    while(p)    {        q=p;        p=p->next;        q->next=head->next;        head->next=q;    }}

以上面图为例子,说白了就是不断的将1后面的节点插入到head后面,即为头插法

完整代码

#include<stdio.h>#include<malloc.h>typedef struct node{    int data;    struct node*next; }node; node*creat() {    node*head,*p,*q;    char ch;    head=(node*)malloc(sizeof(node));    q=head;    ch='*';    puts("单链表尾插法,?结束");    while(ch!='?')    {        int a;         scanf("%d",&a);        p=(node*)malloc(sizeof(node));        p->data=a;        q->next=p;        q=p;        ch=getchar();     }     q->next=NULL;     return(head); } void print(node*a) {    puts("print ");    a=a->next;    while(a!=NULL)    {        printf("%d ",a->data);        a=a->next;     }  } void reverse(node*head){    node*p,*q;    p=head->next;    head->next=NULL;    while(p)    {        q=p;        p=p->next;        q->next=head->next;        head->next=q;    }}  main() {    node*a;    a=creat();    print(a);    reverse(a);    puts("\nhaved reversed:");     print(a);     return 0; }

程序截图
这里写图片描述

就地逆置法

//单链表定义
typedef struct ListNode{
int m_nValue;
ListNode* pNext;
};

//单链表逆置实现

ListNode* ReverseList(ListNode* pHead){    if (pHead == NULL || pHead->pNext == NULL)    {        retrun pHead;    }    ListNode* pRev = NULL;    ListNode* pCur = pHead;    while(pCur != NULL)    {        ListNode* pTemp = pCur;   // 步骤①        pCur = pCur->pNext;       // 步骤②        pTemp->pNext = pRev;      // 步骤③        pRev = pTemp;    }    return pRev;}

下面我们来用图解的方法具体介绍整个代码的实现流程:

初始状态:这里写图片描述

第一次循环:
这里写图片描述

第一次循环过后,步骤①:pTemp指向Head,步骤②:pCur指向P1,步骤③:pTemp->pNext指向NULL。

此时得到的pRev为:这里写图片描述

第二次循环:
这里写图片描述

第二次循环过后,步骤①:pTemp指向P1,步骤②:pCur指向P2,步骤③:pTemp->pNext指向Head。

此时得到的pRev为:这里写图片描述

第三次循环:这里写图片描述

第三次循环过后:步骤①:pTemp指向P2,步骤②:pCur指向P3,步骤③:pTemp->pNext指向P1。

此时得到的pRev为:
这里写图片描述

第四次循环:这里写图片描述

第四次循环过后:步骤①:pTemp指向P3,步骤②:pCur指向NULL,步骤③:pTemp->pNext指向P2。

此时得到的pRev为:
这里写图片描述

至此,单链表的逆置完成。

注就地逆置法转载出:灯火阑珊231

总结

头插法和就地逆置法是有区别的,其区别就在于逆置后的链表如果需要打印的话,那么头插法是从head开始的,而就地逆置则是从表尾开始的,从便捷性来说,头插法还是较之就地逆置法要好上那么一点点,当然因题而异了

原创粉丝点击