您的位置:首页 > 其它

经典算法学习——逆转链表

2016-08-07 16:51 495 查看
       链表在数据结构中是一种非常重要的线性数据结构,也是各类面试笔试中常常涉及的问题。其中最常见的一个问题就是“输入一个链表的头结点,从尾到头反过来打印出每个节点的值”,简单说就是逆转链表。当然,有人会发现,这其实就是剑指Offer中的一道题。这道题的实现我已经上传至  https://github.com/chenyufeng1991/ReverseLinkedList_Stack
      这道题最经典的实现就是使用栈。在我们正向遍历链表的每个节点的时候,分别把每一个节点入栈,等到所有节点入栈后,再从栈顶弹出每一个节点,此时弹出的节点顺序就是链表从尾到头的顺序。而栈结构在C++中使用STL是很容易实现的,代码如下:
/**
* 输入一个链表的头结点,从尾到头打印链表的每一个节点
*/
#include <iostream>
#include <stdlib.h>
#include <stack>

using namespace std;

typedef struct ListNode{
int element;
struct ListNode *next;
}Node;

void CreateLinkedList(Node **head);
void ReverseLinkedList(Node *pNode);

int main(int argc, const char * argv[])
{
Node *pList;
CreateLinkedList(&pList);
ReverseLinkedList(pList);

return 0;
}

/**
* 指针是指向一个变量在内存中的地址;
* 指针的指针是指向一个指针在内存中的地址;
*/
void CreateLinkedList(Node **head)
{
cout<<"依次输入数字创建链表,输入<=0创建结束"<<endl;
*head = (Node *)malloc(sizeof(Node));
memset(*head, 0, sizeof(int));
(*head)->next = NULL;

Node *pInsert;
Node *pMove;
pInsert = (Node *)malloc(sizeof(Node));
memset(pInsert, 0, sizeof(Node));
pInsert->next = NULL;

cin>>pInsert->element;
pMove = *head;
while (pInsert->element > 0)
{
pMove->next = pInsert;
pMove = pInsert;

pInsert = (Node *)malloc(sizeof(Node));
memset(pInsert, 0, sizeof(Node));
pInsert->next = NULL;

cin>>pInsert->element;
}
}

void ReverseLinkedList(Node *pNode)
{
stack<Node *> nodes;

// 要入栈的节点是真正链表的第一个结点,而不是头结点
pNode = pNode->next;
while (pNode != NULL)
{
nodes.push(pNode);
pNode = pNode->next;
}

while (!nodes.empty())
{
Node *top = nodes.top();
cout<<top->element<<" ";
nodes.pop();
}
}


     除上面的思路以外,还有一种办法来实现:在遍历当前链表的时候,取出该节点,用头插法建立一个新链表,新链表就是原链表的逆序。这种实现可以参考我的另一篇博客 C语言实现单链表的逆序打印(带头结点)  。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: