从尾到头打印链表
很容易想到用栈来实现;
其实也可以用递归来实现,递归的本质就是一个栈结构;
如果链表特别长,会导致函数调用的层级很深,从而有可能导致函数调用栈溢出;
现实用栈来实现循环的点吗更容易懂;
ListRev.cpp:
1
2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 |
#include <iostream>
#include <stack> #include <cstdio> #include "List.h" 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 ", 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 ", pHead->m_nValue); } } // 1->2->3->4->5 int main() { 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); ListNode *pHead = pNode1; PrintList(pHead); PrintListReversingly_Iteratively(pHead); printf(" "); PrintListReversingly_Recursively(pHead); printf(" "); DestroyList(pNode1); return 0; } |
运行结果:
PrintList starts.
1 2 3 4 5
PrintList ends.
5 4 3 2 1
5 4 3 2 1
List.h:
1
2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 |
#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:
1
2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 |
#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. "); exit(1); } pCurrent->m_pNext = pNext; } void PrintListNode(ListNode *pNode) { if(pNode == NULL) { printf("The node is NULL "); } else { printf("The key in node is %d. ", pNode->m_nValue); } } void PrintList(ListNode *pHead) { printf("PrintList starts. "); ListNode *pNode = pHead; while(pNode != NULL) { printf("%d ", pNode->m_nValue); pNode = pNode->m_pNext; } printf(" PrintList ends. "); } 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:
1
2 3 4 5 6 7 8 9 10 11 12 |
.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) |