• 数据结构之栈


    一、栈的特点

    (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 
    ");
     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! 
    ");
    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 
    ",nNum);
    125    
    126     for(int i = 0;i < nNum;i++)
    127     {
    128         int val1 = stackVal1.Pop();
    129         printf("%d  ",val1);
    130     }
    131     printf("
    ");
    132 
    133     nNum = stackVal1.GetNum();
    134     printf("------num:%d 
    ",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.
    ");
    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  =================
    ",val);
    186     }
    187     
    188 
    189     return 0;
    190 }

  • 相关阅读:
    go语言判断末尾不同的长字符串的方法
    Go语言高级特性总结——Struct、Map与JSON之间的转化
    MacOS使用常用配置
    关于联盟链的一种激励扩张思路(原创)
    密码学中经典算法及应用
    无线网络
    基础的并查集
    找单词
    找零钱
    最大子矩阵
  • 原文地址:https://www.cnblogs.com/calence/p/11524970.html
Copyright © 2020-2023  润新知