您的位置:首页 > 职场人生

剑指Offer----面试题五:从尾到头打印链表

2016-05-19 22:32 661 查看
转载请注明出处</article/7845927.html>



前述:

链表的创建、结点的插入、结点的删除等操作都只需要20行左右的代码就能实现,其代码量比较适合面试。

链表问题:面试题5“从尾到头输出链表”、面试题13“在O(1)时间删除链表结点”、面试题15“链表中的倒数第k个结点”、面试题16“反转链表”、面试题17“合并两个排序的链表”、面试题37“两个链表的第一个公共结点”、面试题45“圆圈中最后剩下的数字”、面试题27“二叉搜索树与双向链表”、面试题26“复杂链表的赋值”。

题目:

输入一个链表的头结点,从尾到头反过来点每个结点的值。

提示:面试中如果打算修改输入的数据,最好先问面试官是不是允许做修改。

思路一:

遍历的顺序是从头到尾,可是却要从尾到头打印,符合“后进先出”栈的规律。

源代码:
void printReversingly_Iteratively(ListNode *pHead)
{

if (pHead == NULL)
{
std::cout << "The list is empty" << std::endl;
return;
}
else
{
std::stack<ListNode *> st;
ListNode * pNew = pHead;
while (pNew != NULL)
{
st.push(pNew);
pNew = pNew->next;
}

while (!st.empty())
{
std::cout << st.top()->element << "  ";
st.pop();
}
}
}


思路二:

既然想到用栈来实现这个函数,而递归的本质就是一个栈结构,所以本函数也可以用递归来解决。

源代码:
void printReversingly_Recursively(ListNode *pHead)
{
if (pHead != NULL)
{
if (pHead->next != NULL)
printReversingly_Recursively(pHead->next);
std::cout << pHead->element << "  ";
}
}


注意:当链表非常长的时候,就会导致函数调用的层级很深,从而有可能导致函数调用栈溢出。

官方源代码(经过修改):

头文件List.h

#ifndef LIST_NODE_H
#define LIST_NODE_H

namespace ListSpace
{

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

ListNode * CreateListNode(int valude);
void ConnectListNodes(ListNode *pCurrent, ListNode *pNext);
void printListNode(ListNode *pHead);
void printList(ListNode *pHead);
void printReversingly_Iteratively(ListNode *pHead);
void printReversingly_Recursively(ListNode *pHead);
void DestoryList(ListNode **pHead);
void AddToTail(ListNode ** pHead, int value);
void RemoveNode(ListNode ** pHead, int value);

}

#endif


源文件List.cpp

#include"List.h"
#include<iostream>
#include<stack>

namespace ListSpace
{
ListNode * CreateListNode(int value)
{
ListNode *pNew = new ListNode();
pNew->element = value;
pNew->next = NULL;

return pNew;
}

void ConnectListNodes(ListNode *pCurrent, ListNode *pNext)
{
if (pCurrent == NULL)
std::cout << "Linking Error..." << std::endl;
else
{
pCurrent->next = pNext;
}
}

void printListNode(ListNode *pHead)
{
if (pHead == NULL)
std::cout << "The value of this node is empty" << std::endl;
else
std::cout << "The value of this node is " << pHead->element << std::endl;
}

void printList(ListNode *pHead)
{
if (pHead == NULL)
std::cout << "The list is empty" << std::endl;
else
{
ListNode *pNew = pHead;
while (pNew != NULL)
{
std::cout << pNew->element << " ";
pNew = pNew->next;
}
}
}

void printReversingly_Iteratively(ListNode *pHead) { if (pHead == NULL) { std::cout << "The list is empty" << std::endl; return; } else { std::stack<ListNode *> st; ListNode * pNew = pHead; while (pNew != NULL) { st.push(pNew); pNew = pNew->next; } while (!st.empty()) { std::cout << st.top()->element << " "; st.pop(); } } }

void printReversingly_Recursively(ListNode *pHead) { if (pHead != NULL) { if (pHead->next != NULL) printReversingly_Recursively(pHead->next); std::cout << pHead->element << " "; } }

void DestoryList(ListNode **pHead)
{
ListNode *pNew = *pHead;
while (pNew != NULL)
{
*pHead = (*pHead)->next;
delete pNew;
pNew = *pHead;
}
}

void AddToTail(ListNode ** pHead, int value)
{
ListNode *pNew = new ListNode();
pNew->element = value;
pNew->next = NULL;

if (*pHead == NULL)
*pHead = pNew;
else
{
//找到最后一个结点
ListNode *node = *pHead;
while (node ->next != NULL)
node = node->next;

node->next = pNew;
}
}

void RemoveNode(ListNode ** pHead, int value)
{
if (pHead == NULL || *pHead == NULL)
return;

ListNode *pToBeDeleted = NULL;
if ((*pHead)->element == value)
{
pToBeDeleted = *pHead;
*pHead = (*pHead)->next;
}
else
{
ListNode *node = *pHead;
while (node->next != NULL && node->next->element != value)
node = node->next;
if (node->next != NULL && node->next->element == value)
{
pToBeDeleted = node->next;
node->next = node->next->next;
}
}

if (pToBeDeleted != NULL)
{
delete pToBeDeleted;
pToBeDeleted = NULL;
}
}
}


测试文件

#include"List.h"
#include<iostream>

using namespace ListSpace;

void Test(ListNode* pHead)
{
printList(pHead);
printReversingly_Recursively(pHead);
printf("\n");
printReversingly_Recursively(pHead);
}

// 1->2->3->4->5
void Test1()
{
printf("\nTest1 begins.\n");

ListNode* pNode1 = CreateListNode(1);
ListNode* pNode2 = CreateListNode(2);
ListNode* pNode3 = CreateListNode(3);
ListNode* pNode4 = CreateListNode(4);
ListNode* pNode5 = CreateListNode(5);

ConnectListNodes(pNode1, pNode2);
ConnectListNodes(pNode2, pNode3);
ConnectListNodes(pNode3, pNode4);
ConnectListNodes(pNode4, pNode5);

Test(pNode1);

DestoryList(&pNode1);
}

// 只有一个结点的链表: 1
void Test2()
{
printf("\nTest2 begins.\n");

ListNode* pNode1 = CreateListNode(1);

Test(pNode1);

DestoryList(&pNode1);
}

// 空链表
void Test3()
{
printf("\nTest3 begins.\n");

Test(NULL);
}

int main()
{
Test1();
Test2();
Test3();

system("pause");
return 0;
}


运行结果:
Test1 begins.
1  2  3  4  5  5  4  3  2  1
5  4  3  2  1
Test2 begins.
1  1
1
Test3 begins.
The list is empty

请按任意键继续. . .


转载请注明出处</article/7845927.html>
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: