一、栈的特点
(1)栈是一种线性结构,栈中的元素遵循先入后出的原则,最先进入的元素所在位置叫做栈底,最后放入的元素所在位置叫做栈顶。
这种结构类似于盛放羽毛球的圆筒,一端封闭,另一端开口,先放入的羽毛球位于筒的底部(即栈底),后放入的羽毛球位于筒的入口(即栈顶)。
(2)栈也是一种抽象的逻辑结构,依赖于物理结构(如数组、链表)而存在。既可以使用数组实现,也可以使用链表实现。
(3)出栈、入栈的时间复杂都是O(1)。

二、 栈的基本操作
栈的基本操作主要是出栈、入栈、获取栈顶元素等。
(1)入栈
栈的入栈操作只允许从栈顶一侧放入新元素,放入的新元素成为新的栈顶。
(2) 出栈
栈的出栈操作只允许从栈顶弹出,出栈元素的前一个元素变成了新的栈顶。
三、基于数组实现栈
1 #include <iostream>
2 #include <assert.h>
3
4 // 基于数组实现的栈(模板类)
5 template <class T>
6 class ArrayStack
7 {
8 public :
9 ArrayStack(int nCapcity = 8);
10 ~ArrayStack();
11
12 bool Push(const T& ele);
13 T Pop();
14 T& GetPop();
15 int GetNum();
16
17 private:
18 void Resize();
19 private:
20 T* m_pElement;
21 int m_nCapicity;
22 int m_nNum;
23 };
24
25 template<class T>
26 ArrayStack<T>::ArrayStack(int nCapcity)
27 :m_nCapicity(nCapcity)
28 ,m_pElement(new T[nCapcity])
29 ,m_nNum(0)
30 {
31
32 }
33
34 template<class T>
35 ArrayStack<T>::~ArrayStack()
36 {
37 delete[] m_pElement;
38 }
39
40 template<class T>
41 bool ArrayStack<T>::Push(const T& ele)
42 {
43 if(m_pElement == NULL)
44 {
45 printf(" m_pElement == NUL \n");
46 assert(false && "m_pElement == NUL");
47 return false;
48 }
49 if(m_nNum >= m_nCapicity)
50 {
51 Resize();
52 }
53
54 m_pElement[m_nNum] = ele;
55 m_nNum++;
56 return true;
57 }
58
59 template<class T>
60 T ArrayStack<T>::Pop()
61 {
62 if(m_nNum <= 0)
63 {
64 return NULL;
65 }
66
67 m_nNum--;
68 return m_pElement[m_nNum];
69 }
70
71 template<class T>
72 T& ArrayStack<T>::GetPop()
73 {
74 if(m_nNum <= 0)
75 {
76 return NULL;
77 }
78
79 return m_pElement[m_nNum - 1];
80 }
81
82 template<class T>
83 int ArrayStack<T>::GetNum()
84 {
85 return m_nNum;
86 }
87
88 template<class T>
89 void ArrayStack<T>::Resize()
90 {
91 if(NULL == m_pElement)
92 {
93 if(m_nCapicity == 0)
94 {
95 m_nCapicity = 8;
96 }
97 m_pElement = new T[m_nCapicity];
98 return;
99 }
100
101 T* pNewEle = new T[m_nCapicity * 2];
102 for(int i = 0;i < m_nNum;i++)
103 {
104 pNewEle[i] = m_pElement[i];
105 }
106
107 delete[] m_pElement;
108 m_pElement = pNewEle;
109 m_nCapicity = m_nCapicity * 2;
110 }
111
112 int main()
113 {
114 printf("Welcome to stack! \n");
115
116 ArrayStack<int> stackVal1(4);
117 stackVal1.Push(1);
118 stackVal1.Push(10);
119 stackVal1.Push(20);
120 stackVal1.Push(40);
121 stackVal1.Push(60);
122
123 int nNum = stackVal1.GetNum();
124 printf("------num:%d \n",nNum);
125
126 for(int i = 0;i < nNum;i++)
127 {
128 int val1 = stackVal1.Pop();
129 printf("%d ",val1);
130 }
131 printf("\n");
132
133 nNum = stackVal1.GetNum();
134 printf("------num:%d \n",nNum);
135 return 0;
136 }
四、基于链表实现栈
1 #include <iostream>
2 #include <assert.h>
3
4 template<class T>
5 class Node
6 {
7 public:
8 Node():m_pNext(NULL){}
9 Node(T& data):m_Data(data),m_pNext(NULL){}
10 Node(T& data,Node<T>* pNext):m_Data(data),m_pNext(pNext){}
11 public:
12 T m_Data;
13 Node<T>* m_pNext;
14 };
15
16 //单链表
17 template<class T>
18 class SingleList
19 {
20 public:
21 SingleList():m_pHead(NULL),m_pCurrent(NULL),m_nSize(0){}
22 ~SingleList()
23 {
24 Clear();
25 }
26
27 //获取链表元素个数
28 int GetNum()
29 {
30 return m_nSize;
31 }
32
33 //尾部插入新节点
34 bool InsertNode(const T& data)
35 {
36 Node<T>* pNew = new Node<T>();
37 pNew->m_Data = data;
38 pNew->m_pNext = NULL;
39 if(m_pHead == NULL)
40 {
41 m_pHead = pNew;
42 m_pCurrent = pNew;
43 }
44 else
45 {
46 m_pCurrent->m_pNext = pNew;
47 m_pCurrent = pNew;
48 }
49 m_nSize++;
50 return true;
51 }
52
53 //删除节点
54 int DeleteNode()
55 {
56 if(m_nSize == 0 || m_pHead == NULL|| NULL == m_pCurrent)
57 {
58 return -1;
59 }
60
61 if(m_pHead == m_pCurrent)
62 {
63 m_pHead = m_pCurrent->m_pNext;
64 delete m_pCurrent;
65 m_pCurrent = m_pHead;
66 }
67 else
68 {
69 Node<T>* pCurrent = m_pHead;
70 while(pCurrent)
71 {
72 if(pCurrent->m_pNext == m_pCurrent)
73 {
74 pCurrent->m_pNext = m_pCurrent->m_pNext;
75 delete m_pCurrent;
76 m_pCurrent = pCurrent;
77 break;
78 }
79 else
80 {
81 pCurrent = pCurrent->m_pNext;
82 }
83 }
84 }
85
86 m_nSize--;
87 return m_nSize;
88 }
89
90 //获取当前节点数据
91 void GetCurrentNodeData(T& data)
92 {
93 if(m_pCurrent)
94 {
95 data = m_pCurrent->m_Data ;
96 }
97 }
98
99 //设置当前节点数据
100 void SetCurrentNodeData(T& data)
101 {
102 if(m_pCurrent)
103 {
104 m_pCurrent->m_Data = data;
105 }
106 }
107
108 //清空列表
109 void Clear()
110 {
111 if(m_nSize == 0 || m_pHead == NULL)
112 {
113 return;
114 }
115
116 Node<T>* tepCurrent = m_pHead;
117 Node<T>* tepNext = m_pHead->m_pNext;
118
119 while(tepCurrent)
120 {
121 delete tepCurrent;
122 tepCurrent = tepNext;
123 if(tepNext)
124 {
125 tepNext = tepNext->m_pNext;
126 }
127 }
128 m_pHead = NULL;
129 m_pCurrent = NULL;
130 m_nSize = 0;
131 }
132 private:
133 Node<T>* m_pHead;
134 Node<T>* m_pCurrent;
135 int m_nSize;
136 };
137
138 template<class T>
139 class LinkStack
140 {
141 public:
142 LinkStack(){}
143 ~LinkStack(){}
144 //获取元素个数
145 int GetNum()
146 {
147 return m_SingleList.GetNum();
148 }
149
150 //添加新元素
151 bool Push(const T& data)
152 {
153 return m_SingleList.InsertNode(data);
154 }
155
156 //移除栈顶元素
157 T Pop()
158 {
159 T temp;
160 if(GetNum() <= 0)
161 {
162 return -1;
163 }
164 m_SingleList.GetCurrentNodeData(temp);
165 m_SingleList.DeleteNode();
166 return temp;
167 }
168 private:
169 SingleList<T> m_SingleList;
170 };
171
172 int main()
173 {
174 printf("Welcome to link stack.\n");
175 LinkStack<int> stackVal2;
176 stackVal2.Push(100);
177 stackVal2.Push(200);
178 stackVal2.Push(300);
179 stackVal2.Push(500);
180
181 int nNum = stackVal2.GetNum();
182 for(int i = 0;i < nNum;i++)
183 {
184 int val = stackVal2.Pop();
185 printf("Pop:%d =================\n",val);
186 }
187
188
189 return 0;
190 }