【面试题五】从尾到头打印链表
2013-11-30 15:50
417 查看
从尾到头打印链表
很容易想到荣栈来实现;
其实也可以用递归来实现,递归的本质就是一个栈结构;
如果链表特别长,会导致函数调用的层级很深,从而有可能导致函数调用栈溢出;
现实用栈来实现循环的点吗更容易懂;
ListRev.cpp:
List.h:
List.cpp:
Makefile:
运行结果:
很容易想到荣栈来实现;
其实也可以用递归来实现,递归的本质就是一个栈结构;
如果链表特别长,会导致函数调用的层级很深,从而有可能导致函数调用栈溢出;
现实用栈来实现循环的点吗更容易懂;
ListRev.cpp:
#include <iostream> #include "List.h" #include <stack> #include <cstdio> using namespace std; void PrintListReversingly_Iteratively(ListNode* pHead) { std::stack<ListNode*> nodes; ListNode* pNode = pHead; while(pNode != NULL) { nodes.push(pNode); pNode = pNode->m_pNext; } while(!nodes.empty()) { pNode = nodes.top(); printf("%d\t", pNode->m_nValue); nodes.pop(); } } void PrintListReversingly_Recursively(ListNode* pHead) { if(pHead != NULL) { if (pHead->m_pNext != NULL) { PrintListReversingly_Recursively(pHead->m_pNext); } printf("%d\t", pHead->m_nValue); } } void Test(ListNode* pHead) { PrintList(pHead); PrintListReversingly_Iteratively(pHead); printf("\n"); PrintListReversingly_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); DestroyList(pNode1); } // 只有一个结点的链表: 1 void Test2() { printf("\nTest2 begins.\n"); ListNode* pNode1 = CreateListNode(1); Test(pNode1); DestroyList(pNode1); } // 空链表 void Test3() { printf("\nTest3 begins.\n"); Test(NULL); } int main() { Test1(); Test2(); Test3(); return 0; }
List.h:
#ifndef _List_H_ #define _List_H_ struct ListNode { int m_nValue; ListNode* m_pNext; }; ListNode* CreateListNode(int value); void ConnectListNodes(ListNode* pCurrent, ListNode* pNext); void PrintListNode(ListNode* pNode); void PrintList(ListNode* pHead); void DestroyList(ListNode* pHead); void AddToTail(ListNode** pHead, int value); void RemoveNode(ListNode** pHead, int value); #endif /*_List_H_*/
List.cpp:
#include "List.h" #include <stdio.h> #include <stdlib.h> ListNode* CreateListNode(int value) { ListNode* pNode = new ListNode(); pNode->m_nValue = value; pNode->m_pNext = NULL; return pNode; } void ConnectListNodes(ListNode* pCurrent, ListNode* pNext) { if(pCurrent == NULL) { printf("Error to connect two nodes.\n"); exit(1); } pCurrent->m_pNext = pNext; } void PrintListNode(ListNode* pNode) { if(pNode == NULL) { printf("The node is NULL\n"); } else { printf("The key in node is %d.\n", pNode->m_nValue); } } void PrintList(ListNode* pHead) { printf("PrintList starts.\n"); ListNode* pNode = pHead; while(pNode != NULL) { printf("%d\t", pNode->m_nValue); pNode = pNode->m_pNext; } printf("\nPrintList ends.\n"); } void DestroyList(ListNode* pHead) { ListNode* pNode = pHead; while(pNode != NULL) { pHead = pHead->m_pNext; delete pNode; pNode = pHead; } } void AddToTail(ListNode** pHead, int value) { ListNode* pNew = new ListNode(); pNew->m_nValue = value; pNew->m_pNext = NULL; if(*pHead == NULL) { *pHead = pNew; } else { ListNode* pNode = *pHead; while(pNode->m_pNext != NULL) pNode = pNode->m_pNext; pNode->m_pNext = pNew; } } void RemoveNode(ListNode** pHead, int value) { if(pHead == NULL || *pHead == NULL) return; ListNode* pToBeDeleted = NULL; if((*pHead)->m_nValue == value) { pToBeDeleted = *pHead; *pHead = (*pHead)->m_pNext; } else { ListNode* pNode = *pHead; while(pNode->m_pNext != NULL && pNode->m_pNext->m_nValue != value) pNode = pNode->m_pNext; if(pNode->m_pNext != NULL && pNode->m_pNext->m_nValue == value) { pToBeDeleted = pNode->m_pNext; pNode->m_pNext = pNode->m_pNext->m_pNext; } } if(pToBeDeleted != NULL) { delete pToBeDeleted; pToBeDeleted = NULL; } }
Makefile:
.PHONY:clean CPP=g++ CFLAGS=-Wall -g BIN=test OBJS=ListRev.o List.o LIBS= $(BIN):$(OBJS) $(CPP) $(CFLAGS) $^ -o $@ $(LIBS) %.o:%.cpp $(CPP) $(CFLAGS) -c $< -o $@ clean: rm -f *.o $(BIN)
运行结果:
Test1 begins. PrintList starts. 1 2 3 4 5 PrintList ends. 5 4 3 2 1 5 4 3 2 1 Test2 begins. PrintList starts. 1 PrintList ends. 1 1 Test3 begins. PrintList starts. PrintList ends.
相关文章推荐
- 经典面试题——链表从尾到头打印
- 面试题5 从尾到头打印链表
- 剑指offer|面试题5:从尾到头打印链表(Java实现)
- 剑指offer面试题[5]-从尾到头打印链表
- 面试题5-从尾到头打印链表
- 【面试题5】从尾到头打印链表
- 剑指Offer_面试题05_从尾到头打印链表
- 剑指Offer面试题6:从尾到头打印链表
- 面试题:从尾到头打印链表
- 【C语言】单链表的相关热点面试题(包括:从尾到头打印,逆置,冒泡,寻找中间节点,倒数k节点)
- 面试题5:从尾到头打印链表
- 《剑指offer》面试题5:从尾到头打印链表
- 剑指Offer 面试题5 从尾到头打印链表
- 剑指offer|面试题5:从尾到头打印链表(Java代码)
- 面试题5:从尾到头打印链表
- 剑指Offer:面试题5——从尾到头打印链表(java实现)
- 剑指offer面试题5:从尾到头打印链表
- 剑指Offer面试题5(Java版):从尾到头打印链表
- 剑指offer--面试题5:从尾到头打印链表
- 《剑指Offer》面试题:从尾到头打印链表