数据结构面试之三——栈的常见操作

本文详细介绍了如何使用数组和链表两种不同数据结构实现栈的基本操作,包括初始化、销毁、判断栈是否为空或满、入栈、出栈等核心功能,并提供了完整的C++代码实现。

数据结构面试之三——栈的常见操作

题注:《面试宝典》有相关习题,但思路相对不清晰,排版有错误,作者对此参考相关书籍和自己观点进行了重写,供大家参考。

三、栈的基本操作

3.1用数组构造栈

【注意以下几点】:

1.基于数组的栈的三要素:1)栈的最大容量maxSize; 2)栈的当前容量=当前栈中元素的个数=栈顶top-1;3)动态数组存储栈的元素 Type* list;

       2.对于出栈、入栈的操作要对应先判断栈空、栈满;如果空、满要有异常处理或错误提示。

       3.注意入栈push操作,先入栈后top+1;出栈pop则相反,先top-1,再出栈。【注意因为,top指向数组中最后一个元素的下一个位置】。

       4.拷贝构造函数和赋值函数要注意,尤其赋值的时候,避免自身赋值、同时要注意大小不一致的不能完成赋值操作,要有相关提示。

      

[cpp]  view plain copy
  1.  template<typenameType>  
  2. class arrStack  
  3. {  
  4. public:  
  5.        arrStack(intnSize=100);  
  6.        ~arrStack();  
  7.        arrStack(constarrStack& copyStack);  
  8.        arrStack&operator=(const arrStack& otherStack);  
  9.    
  10.        voidinitializeStack();  
  11.        void destroyStack();  
  12.        bool isStackEmpty();  
  13.        bool isStackFull();  
  14.        void push(constType& item);  
  15.        void pop(Type&poppedItem);  
  16.    
  17. private:  
  18.        int maxSize;  
  19.        int top;  
  20.        Type* list;  
  21. };  
  22.    
  23. template<typename Type>  
  24. arrStack<Type>::arrStack(int nSize=100)  
  25. {  
  26.        if(nSize < 0)  
  27.        {  
  28.               nSize = 100;  
  29.               list = newType[nSize];  
  30.               top = 0;  
  31.               maxSize = 100;  
  32.        }  
  33.        else  
  34.        {  
  35.               list = newType[nSize];  
  36.               top = 0;  
  37.               maxSize =nSize;  
  38.        }  
  39. }  
  40.    
  41. template<typename Type>  
  42. arrStack<Type>::~arrStack()  
  43. {  
  44.        if(!list)  
  45.        {  
  46.               delete[]list;                //注意数组的删除,为delete []list;  
  47.               list = NULL;  
  48.        }  
  49. }  
  50.    
  51. template<typename Type>  
  52. arrStack<Type>::arrStack(const arrStack& copyStack)  
  53. {  
  54.        maxSize =copyStack.maxSize;  
  55.        top = copyStack.top;  
  56.        list = newType[maxSize];           //注意需要自定义大小,容易出错.  
  57.        forint i = 0; i <top; i++)  
  58.        {  
  59.               list[i] =copyStack.list[i];  
  60.        }  
  61. }  
  62.    
  63. template<typename Type>  
  64. arrStack<Type>& arrStack<Type>::operator=(constarrStack& otherStack)  
  65. {  
  66.        if(this ==&otherStack)  
  67.        {  
  68.               cout <<"can't copy oneSelf!" << endl;  
  69.               return *this;  
  70.        }  
  71.        else  
  72.        {  
  73.               if(maxSize !=otherStack.maxSize)  
  74.               {  
  75.                      cout<< "The Size of two stack are not equal!" << endl;  
  76.                      return*this;  
  77.               }  
  78.               else  
  79.               {  
  80.                      maxSize= otherStack.maxSize;  
  81.                      top =otherStack.top;  
  82.                      for( inti = 0; i < top; i++)  
  83.                      {  
  84.                             list[i]= otherStack.list[i];  
  85.                      }//endfor  
  86.                      return*this;  
  87.               }  
  88.        }//end else  
  89. }  
  90.    
  91. template<typename Type>  
  92. void arrStack<Type>::initializeStack()  
  93. {  
  94.        destroyStack();  
  95. }  
  96.    
  97. template<typename Type>  
  98. void arrStack<Type>::destroyStack()  
  99. {  
  100.        top = 0;  
  101. }  
  102.    
  103. template<typename Type>  
  104. bool arrStack<Type>::isStackEmpty()  
  105. {  
  106.        return (top == 0);  
  107. }  
  108.    
  109. template<typename Type>  
  110. bool arrStack<Type>::isStackFull()  
  111. {  
  112.        return (top ==maxSize);  
  113. }  
  114.    
  115. template<typename Type>  
  116. void arrStack<Type>::push(const Type& item)  
  117. {  
  118.        if(!isStackFull())  
  119.        {  
  120.               list[top] =item;  
  121.               top++;  
  122.        }  
  123.        else  
  124.        {  
  125.               cout <<"The Stack was already Full!" << endl;  
  126.        }  
  127. }  
  128.    
  129. template<typename Type>  
  130. void arrStack<Type>::pop(Type& poppedItem)  
  131. {  
  132.        if(!isStackEmpty())  
  133.        {  
  134.               top--;  
  135.               poppedItem =list[top];  
  136.        }  
  137.        else  
  138.        {  
  139.               cout <<"The Stack was already Empty!" << endl;  
  140.        }  
  141. }  

3.2用链表构造栈

链表构造栈注意:

1) 判断栈空的标记是top==NULL;由于栈的空间可以动态分配,因此可以认为链栈不会满。

2) 栈的入栈Push操作要先判定栈是否已经满,非满才可以入栈。先入栈,再调整top指针;

3) 栈的出栈Pop操作要先判定栈是否已空,非空才可以出栈。先调整top指针,再出栈,并删除原结点。

4) 可以加count判定当前结点的个数。

[cpp]  view plain copy
  1. template<typename Type>  
  2. struct nodeType  
  3. {  
  4.        Type info;  
  5.        nodeType* link;  
  6. };  
  7.    
  8. template<typename Type>  
  9. class linkedStack  
  10. {  
  11. public:  
  12.        linkedStack();  
  13.        ~linkedStack();  
  14.        linkedStack(constlinkedStack<Type>&);  
  15.        linkedStack&operator=(const linkedStack<Type>&);  
  16.    
  17.        voidinitializeStack();  
  18.        void destroyStack();  
  19.        bool isStackEmpty()const;  
  20.        bool isStackFull()const;  
  21.        void push(constType& item);  
  22.        void pop(Type&poppedItem);  
  23.        void nodeCount();  
  24.         
  25.        voidreversePrint();          //逆向打印的非递归实现...  
  26.    
  27. private:  
  28.        nodeType<Type>*top;  
  29.        int count;         //统计节点个数  
  30. };  
  31.    
  32. template<typename Type>  
  33. linkedStack<Type>::linkedStack()  
  34. {  
  35.        count = 0;  
  36.        top = NULL;  
  37. }  
  38.    
  39. template<typename Type>  
  40. linkedStack<Type>::~linkedStack()  
  41. {  
  42.        while( top != NULL )  
  43.        {  
  44.               nodeType<Type>*tempNode = new nodeType<Type>;  
  45.               tempNode = top;  
  46.               top =top->link;  
  47.    
  48.               deletetempNode;  
  49.        }//end if  
  50. }  
  51.   
  52.    
  53. template<typename Type>  
  54. linkedStack<Type>::linkedStack(constlinkedStack<Type>& copyStack)  
  55. {  
  56.        if(copyStack.top !=NULL)  
  57.        {  
  58.               nodeType<Type>*current;  
  59.               nodeType<Type>*first;  
  60.               nodeType<Type>*newNode;  
  61.                
  62.               top = newnodeType<Type>;  
  63.               top->info =copyStack.top->info;                //此处的top不能直接用,内存报错!  
  64.               top->link =copyStack.top->link;  
  65.    
  66.               first =top;                        //first跟进当前链表...  
  67.               current =copyStack.top->link;      //current跟进copy链表...  
  68.               while( current!= NULL)  
  69.               {  
  70.                      newNode= new nodeType<Type>;  
  71.                      newNode->link= current->link;  
  72.                      newNode->info= current->info;  
  73.    
  74.                      first->link= newNode;  
  75.                      first =newNode;  
  76.                      current= current->link;  
  77.               }//end while  
  78.               count =copyStack.count;  
  79.        }//end if  
  80.        else  
  81.        {  
  82.               top = NULL;  
  83.               count = 0;  
  84.        }  
  85. }  
  86.    
  87. template<typename Type>  
  88. linkedStack<Type>&linkedStack<Type>::operator=(const linkedStack<Type>&otherStack)  
  89. {  
  90.        //1避免自身赋值  
  91.        if(this ==&otherStack)  
  92.        {  
  93.               cout <<"Can't copy oneself!" << endl;  
  94.               return *this;  
  95.        }  
  96.        //2其他  
  97.        else  
  98.        {  
  99.               if(top != NULL)  
  100.               {  
  101.                      destroyStack();  
  102.               }  
  103.               if(otherStack.top!= NULL)  
  104.               {  
  105.                      nodeType<Type>*current;  
  106.                      nodeType<Type>*first;  
  107.                      nodeType<Type>*newNode;  
  108.    
  109.                      top =new nodeType<Type>;  
  110.                      top->info= otherStack.top->info;  
  111.                      top->link= otherStack.top->link;  
  112.                      first =top;                        //first跟进当前链表...  
  113.                      current= otherStack.top->link;      //current跟进copy链表...  
  114.                      while(current != NULL)  
  115.                      {  
  116.                             newNode= new nodeType<Type>;  
  117.                             newNode->link= current->link;  
  118.                             newNode->info= current->info;  
  119.    
  120.                             first->link= newNode;  
  121.                             first= newNode;  
  122.                             current= current->link;  
  123.                      }//endwhile  
  124.                      count =otherStack.count;  
  125.               }//end if  
  126.               else  
  127.               {  
  128.                      top =NULL;  
  129.                      count =0;  
  130.               }  
  131.               return *this;  
  132.        }  
  133. }  
  134.    
  135. template<typename Type>  
  136. void linkedStack<Type>::initializeStack()  
  137. {  
  138.        destroyStack();  
  139. }  
  140.    
  141. template<typename Type>  
  142. void linkedStack<Type>::destroyStack()  
  143. {  
  144.        count = 0;  
  145.        top = NULL;  
  146. }  
  147.    
  148. template<typename Type>  
  149. bool linkedStack<Type>::isStackEmpty() const  
  150. {  
  151.        return (count == 0);  
  152. }  
  153.    
  154. template<typename Type>  
  155. bool linkedStack<Type>::isStackFull() const //空间非固定,动态申请!  
  156. {  
  157.        return false;  
  158. }  
  159.    
  160. template<typename Type>  
  161. void linkedStack<Type>::push(const Type& item)  
  162. {  
  163.        if(!isStackFull())  
  164.        {  
  165.               nodeType<Type>*newNode = new nodeType<Type>;  
  166.               newNode->info= item;  
  167.               newNode->link= NULL;  
  168.    
  169.               if(top == NULL)  
  170.               {  
  171.                      top = newNode;  
  172.               }  
  173.               else  
  174.               {  
  175.                      newNode->link= top;  
  176.                      top =newNode;  
  177.               }  
  178.               count++;  
  179.               cout <<item << " was pushed!" << endl;  
  180.        }  
  181. }  
  182.    
  183. template<typename Type>  
  184. void linkedStack<Type>::pop(Type& poppedItem)  
  185. {  
  186.        if(!isStackEmpty())  
  187.        {  
  188.               nodeType<Type>*temp = new nodeType<Type>;  
  189.               temp = top;  
  190.               poppedItem =top->info;  
  191.               top =top->link;  
  192.                
  193.               count--;  
  194.               cout <<poppedItem << " was popped!" << endl;  
  195.               delete temp;  
  196.        }  
  197. }  
  198.    
  199. template<typename Type>  
  200. void linkedStack<Type>::nodeCount()  
  201. {  
  202.        cout <<"nodeCount = " << count << endl;  
  203. }  
  204.    
  205. //上一节的递归实现逆向链表打印,这是非递归的实现。  
  206. template<typename Type>  
  207. void linkedStack<Type>::reversePrint()          //逆向打印的非递归实现...  
  208. {  
  209. //  注释部分可作为链表调用栈的非递归实现。  
  210. //    nodeType<Type>*current = new nodeType<Type>;  
  211. //    current = top;  
  212. //    while(current != NULL)  
  213. //    {  
  214. //           pop(current->info);  
  215. //           current =current->link;  
  216. //    }  
  217.        int poppedItem = 0;  
  218.        while(!isStackEmpty())  
  219.        {  
  220.               pop(poppedItem);  
  221.        }  
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值