逆序单链表的高效算法

链表反转是很多笔试面试常考之题,既然这么常见那就好好研究下。其实链表反转方法很多,主要有一下几种办法:

1、重建新链表,使用头插法将原链表元素放入,时空复杂度较大,同时如果加入“就地逆序不新建”等限制条件,该算法便不可用;

2、堆栈法:将原链表元素依序push如堆栈中,然后再pop入新链表中,时空复杂度依然过大,但是思路不错;

3、修正的头插法: 对方法1的头插法进行改进,不插入新建列表中,而是插入已置空的当然链表中,只修改各节点的next指向,时间复杂度只有O(n)。是较为完美的解决方案。

总结:其实还存在一些变形的算法,比如笔者刚开始开始自制了一种类似头插法的算法,不过需要增加一个零时指针保存当前指针在原链表中的next节点,时间复杂度同算法3是相同的,但是在参考了一些数据结构书后发现这三种算法相对思路更加清晰更“规范”些。尤其是算法三。

有了以上讨论,写出反转链表的算法就很容易了,以下是算法3的C语言实现:

《逆序单链表的高效算法》
#include 
<
stdio.h
>

《逆序单链表的高效算法》#include 

<
stdlib.h
>

《逆序单链表的高效算法》
《逆序单链表的高效算法》

#define
 LINK_LENGTH 15

《逆序单链表的高效算法》
《逆序单链表的高效算法》typedef 

struct
 _Node
《逆序单链表的高效算法》《逆序单链表的高效算法》

《逆序单链表的高效算法》
{
《逆序单链表的高效算法》    
int data;
《逆序单链表的高效算法》    
struct _Node *next;
《逆序单链表的高效算法》}

Node, 
*
NodePtr;
《逆序单链表的高效算法》
《逆序单链表的高效算法》

void
 CreateLinklist(NodePtr pHead)
《逆序单链表的高效算法》《逆序单链表的高效算法》

《逆序单链表的高效算法》
{
《逆序单链表的高效算法》    NodePtr pPrev, pCurr;
《逆序单链表的高效算法》    
int i = 0;
《逆序单链表的高效算法》    pPrev 
= pHead;
《逆序单链表的高效算法》    
for(i = 0; i < LINK_LENGTH; i++)
《逆序单链表的高效算法》《逆序单链表的高效算法》    
《逆序单链表的高效算法》{
《逆序单链表的高效算法》        pCurr 
= (NodePtr)malloc(sizeof(Node));
《逆序单链表的高效算法》        pCurr
->data = i + 1;
《逆序单链表的高效算法》        pCurr
->next = NULL;
《逆序单链表的高效算法》        pPrev
->next = pCurr;
《逆序单链表的高效算法》        pPrev 
= pCurr;
《逆序单链表的高效算法》    }

《逆序单链表的高效算法》}


《逆序单链表的高效算法》
《逆序单链表的高效算法》

void
 ReverseLinklist(NodePtr pHead)
《逆序单链表的高效算法》《逆序单链表的高效算法》

《逆序单链表的高效算法》
{
《逆序单链表的高效算法》    NodePtr pCurr, pTmp;
《逆序单链表的高效算法》
《逆序单链表的高效算法》    pCurr 
= pHead->next;
《逆序单链表的高效算法》    pHead
->next = NULL; // Empty the original linklist
《逆序单链表的高效算法》
    while(pCurr != NULL)
《逆序单链表的高效算法》《逆序单链表的高效算法》    
《逆序单链表的高效算法》{
《逆序单链表的高效算法》        pTmp 
= pCurr->next;
《逆序单链表的高效算法》        
// Insert to head
《逆序单链表的高效算法》
        pCurr->next = pHead->next;
《逆序单链表的高效算法》        pHead
->next = pCurr;
《逆序单链表的高效算法》        pCurr 
= pTmp;
《逆序单链表的高效算法》    }

《逆序单链表的高效算法》}


《逆序单链表的高效算法》
《逆序单链表的高效算法》

void
 PrintLinklist(NodePtr pHead)
《逆序单链表的高效算法》《逆序单链表的高效算法》

《逆序单链表的高效算法》
{
《逆序单链表的高效算法》    NodePtr pCurr 
= pHead->next;
《逆序单链表的高效算法》
《逆序单链表的高效算法》    
while(pCurr != NULL)
《逆序单链表的高效算法》《逆序单链表的高效算法》    
《逆序单链表的高效算法》{
《逆序单链表的高效算法》        printf(
%d , pCurr->data);
《逆序单链表的高效算法》        pCurr 
= pCurr->next;
《逆序单链表的高效算法》    }

《逆序单链表的高效算法》    printf(
\n);
《逆序单链表的高效算法》}


《逆序单链表的高效算法》
《逆序单链表的高效算法》

int
 main()
《逆序单链表的高效算法》《逆序单链表的高效算法》

《逆序单链表的高效算法》
{
《逆序单链表的高效算法》    NodePtr pHead 
= NULL;
《逆序单链表的高效算法》    pHead 
= (NodePtr)malloc(sizeof(Node));
《逆序单链表的高效算法》    pHead
->data = 1;   // Head always not in real linklist.
《逆序单链表的高效算法》
    pHead->next = NULL;
《逆序单链表的高效算法》    CreateLinklist(pHead);
《逆序单链表的高效算法》
《逆序单链表的高效算法》    printf(
Original Linklist: );
《逆序单链表的高效算法》    PrintLinklist(pHead);
《逆序单链表的高效算法》
《逆序单链表的高效算法》    
// Reverse
《逆序单链表的高效算法》
    ReverseLinklist(pHead);
《逆序单链表的高效算法》    printf(
Reversed Linklist: );
《逆序单链表的高效算法》    PrintLinklist(pHead);
《逆序单链表的高效算法》
《逆序单链表的高效算法》    system(
pause);
《逆序单链表的高效算法》    
return 0;
《逆序单链表的高效算法》}


《逆序单链表的高效算法》

    原文作者:EricYang
    原文地址: https://www.cnblogs.com/EricYang/archive/2009/09/06/1561353.html
    本文转自网络文章,转载此文章仅为分享知识,如有侵权,请联系博主进行删除。
点赞