- 栈的定义--Stack
栈是只允许在末端进行插入和删除的线性表。栈具有后进先出的特性(LIFO ,Last In Fast Out)。
学过数据结构的人都知道:栈可以用两种方式来实现,一种方法是用数组实现栈,这种栈成为静态栈;另外一种方法是用链表实现栈,这种栈叫做动态栈。
- 栈提供如下操作
s.empty() 如果栈为空返回true,否则返回false s.size() 返回栈中元素的个数 s.pop() 删除栈顶元素但不返回其值 s.top() 返回栈顶的元素,但不删除该元素 s.push() 在栈顶压入新元素
- 栈的实现
下面是用C++实现的一个栈结构的源码(顺序表)
1 #pragma once 2 #include<iostream> 3 #include<assert.h> 4 using namespace std; 5 template<typename T> 6 class Stack 7 { 8 public: 9 Stack() 10 :array(NULL) 11 , size(0) 12 , capacity(0) 13 {} 14 ~Stack() 15 { 16 if (array != NULL) 17 { 18 delete[] array; 19 } 20 capacity = 0; 21 size = 0; 22 } 23 Stack(const Stack<T>& s) 24 { 25 array = new T[s.size]; 26 memcpy(array, s.array, sizeof(T)*s.size); 27 size =s.size; 28 capacity = s.capacity; 29 } 30 Stack<T>& operator=( const Stack<T>& s) 31 { 32 capacity = s.capacity; 33 size = s.size; 34 this->array =s.array; 35 return *this; 36 } 37 void Print() 38 { 39 for (int index = 0; index < size; index++) 40 { 41 cout << array[index] << " "; 42 } 43 cout << endl; 44 } 45 void Push(const T& x) 46 { 47 _CheckCapacity(); 48 49 array[size++] = x; 50 } 51 52 void Pop() 53 { 54 assert(size > 0); 55 --size; 56 } 57 58 size_t Size() 59 { 60 return size; 61 } 62 63 bool Empty() 64 { 65 return size == 0; 66 } 67 68 const T& Top() 69 { 70 assert(size > 0); 71 72 return array[size - 1]; 73 } 74 protected: 75 void _CheckCapacity() 76 { 77 if (size >= capacity) 78 { 79 T *temp = new T[capacity * 2 + 3]; 80 for (int index = 0; index < size; index++) 81 { 82 temp[index] =array[index]; 83 } 84 delete[] array; 85 array = temp; 86 capacity = capacity * 2 + 3; 87 } 88 89 } 90 91 protected: 92 T * array; 93 size_t size; 94 size_t capacity; 95 }; 96 void fun() 97 { 98 Stack<int> s; 99 s.Push(6); 100 s.Push(7); 101 s.Push(8); 102 s.Push(9); 103 s.Print(); 104 cout << s.Top() << " "; 105 s.Pop(); 106 } 107 void main() 108 { 109 fun(); 110 system("pause"); 111 }
- 栈的应用
1.算术表达式求值。波兰表达式(后缀表达式)
实现:
1 #include <iostream> 2 #include <assert.h> 3 #include"stack" 4 using namespace std; 5 6 enum Type 7 { 8 OP_NUM, 9 OP_SYMBOL 10 }; 11 12 enum OP_SMB 13 { 14 ADD, 15 SUB, 16 MUL, 17 DIV, 18 }; 19 20 struct Cell 21 { 22 Type _type; 23 int _value; 24 }; 25 26 Cell RNPArray[11] = 27 { 28 { OP_NUM, 12 }, 29 { OP_NUM, 3 }, 30 { OP_NUM, 4 }, 31 { OP_SYMBOL, ADD }, 32 { OP_SYMBOL, MUL }, 33 { OP_NUM, 6 }, 34 { OP_SYMBOL, SUB }, 35 { OP_NUM, 8 }, 36 { OP_NUM, 2 }, 37 { OP_SYMBOL, DIV }, 38 { OP_SYMBOL, ADD }, 39 }; 40 41 int CountRNP(Cell* a, size_t size) 42 { 43 stack<int> s; 44 for (int i = 0; i < size; ++i) 45 { 46 if (a[i]._type == OP_NUM) 47 { 48 s.push(a[i]._value); 49 } 50 else if (a[i]._type == OP_SYMBOL) 51 { 52 int right = s.top(); 53 s.pop(); 54 int left = s.top(); 55 s.pop(); 56 57 switch (a[i]._value) 58 { 59 case ADD: 60 s.push(left + right); 61 break; 62 case SUB: 63 s.push(left - right); 64 break; 65 case MUL: 66 s.push(left * right); 67 break; 68 case DIV: 69 s.push(left / right); 70 break; 71 } 72 } 73 } 74 return s.top(); 75 } 76 void test() 77 { 78 79 int ret=CountRNP(RNPArray, sizeof(RNPArray) / sizeof(RNPArray[0])); 80 cout << ret; 81 } 82 int main() 83 { 84 test(); 85 return 0; 86 }
2.迷宫问题
1 #define _CRT_SECURE_NO_WARNINGS 1 2 #include<iostream> 3 #include<stack> 4 #include<assert.h> 5 using namespace std; 6 //从文件获取初始迷宫地图 7 void GetMazeMap(int *maze, int rows, int cols) 8 { 9 assert(maze); 10 FILE *fOut = fopen("MazeMap.txt", "r"); 11 assert(fOut); 12 for (int i = 0; i < rows; i++) 13 { 14 for (int j = 0; j < cols;) 15 { 16 char ch = fgetc(fOut); 17 if (ch == '0' || ch == '1') 18 { 19 maze[i*cols + j] = ch - '0'; 20 j++; 21 } 22 } 23 } 24 fclose(fOut); 25 } 26 //打印迷宫地图 27 void PrintMazeMap(int*maze, int rows, int cols) 28 { 29 assert(maze); 30 for (int i = 0; i < rows; i++) 31 { 32 for (int j = 0; j < cols; j++) 33 { 34 cout << maze[i*cols + j] << " "; 35 } 36 cout << endl; 37 } 38 cout << endl; 39 } 40 struct Point 41 { 42 size_t row; 43 size_t col; 44 }; 45 //检查该点是否为可通行 46 bool CheckIsAccess(int *maze, int rows, int cols,Point cur) 47 { 48 assert(maze); 49 if (cur.row < rows&&cur.col < cols&& (maze[cur.row*cols + cur.col] == 0)) 50 { 51 return true; 52 } 53 return false; 54 } 55 //获取走出迷宫路径 56 stack<Point> GetMazePath(int* maze, int rows, int cols, Point entry) 57 { 58 assert(maze); 59 stack<Point> path; 60 Point cur = entry; 61 path.push(entry); 62 maze[cur.row*cols + cur.col] = 2; 63 64 while (!path.empty()) 65 { 66 Point cur = path.top(); 67 Point next = cur; 68 if (next.row ==rows-1) 69 { 70 return path; 71 } 72 //试探 上 73 next = cur; 74 next.row--; 75 if (CheckIsAccess(maze, 10, 10, next)) 76 { 77 path.push(next); 78 maze[next.row*cols + next.col] = 2; 79 continue; 80 } 81 //下 82 next = cur; 83 next.row++; 84 if (CheckIsAccess(maze, 10, 10, next)) 85 { 86 path.push(next); 87 maze[next.row*cols + next.col] = 2; 88 continue; 89 } 90 //左 91 next = cur; 92 next.col--; 93 if (CheckIsAccess(maze, 10, 10, next)) 94 { 95 path.push(next); 96 maze[next.row*cols + next.col] = 2; 97 continue; 98 } 99 //右 100 next = cur; 101 next.col++; 102 if (CheckIsAccess(maze, 10, 10, next)) 103 { 104 path.push(next); 105 maze[next.row*cols + next.col] = 2; 106 continue; 107 } 108 } 109 cout << "Not have exit" << endl; 110 return path; 111 } 112 void TestMaze() 113 { 114 int maze[10][10] = {}; 115 116 GetMazeMap((int *)maze, 10, 10); 117 PrintMazeMap((int*)maze, 10, 10); 118 Point entry = { 1, 0 }; 119 GetMazePath((int*)maze, 10, 10, entry); 120 PrintMazeMap((int*)maze, 10, 10); 121 } 122 int main() 123 { 124 TestMaze(); 125 //system("pause"); 126 getchar(); 127 return 0; 128 }