数据结构之栈

孤街醉人 提交于 2019-11-29 17:36:11

一、栈的特点

(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 }

 

 

 

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!