数据结构面试之四——队列的常见操作

数据结构面试之四——队列的常见操作

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

四、队列的基本操作

1.用数组构造队列

队列即是满足先进先出的链表。用数组存储的话,同样需要满足队列头front出栈,队列末尾rear入栈。而对于数组来讲,rear和front可以代表数组头和尾。不能简单的固定rear和front的大小为maxSize和0,因为可能出现中间元素为空的现象。所以,对于数组队列来讲,可以想象成环式存储,因为每一次入队后rear+1,每一次出队后front+1。这就需要控制front和rear的大小,每一次修改只要满足front=(front+1)%maxSize,rear=(rear+1)%maxSize即可满足要求。

       同样需要注意:入队操作前先判定队列是否已经满;出队操作前先判定队列是否为空。

[cpp]  view plain copy
  1. template<typename Type>  
  2. class arrQueue  
  3. {  
  4. public:  
  5.        arrQueue(intnSize=100);  
  6.        ~arrQueue();  
  7.        arrQueue(constarrQueue<Type>& copyQueue);  
  8.        arrQueue&operator=(const arrQueue<Type>& otherQueue);  
  9.    
  10.        voidinitializeQueue();  
  11.        void destroyQueue();  
  12.        bool isQueueEmpty();  
  13.        bool isQueueFull();  
  14.        void addQueue(constType& item);  
  15.        void deQueue(Type&deletedItem);  
  16.    
  17. private:  
  18.        int maxSize;  
  19.        int rear;  
  20.        int front;  
  21.        Type* list;  
  22. };  
  23.    
  24. template<typename Type>  
  25. arrQueue<Type>::arrQueue(int nSize=100)  
  26. {  
  27.        if(nSize < 0)  
  28.        {  
  29.               nSize = 100;  
  30.               list = newType[nSize];  
  31.               front = 0;  
  32.               rear = 0;  
  33.               maxSize = 100;  
  34.        }  
  35.        else  
  36.        {  
  37.               list = newType[nSize];  
  38.               front = 0;  
  39.               rear = 0;  
  40.               maxSize =nSize;  
  41.        }  
  42. }  
  43.    
  44. template<typename Type>  
  45. arrQueue<Type>::~arrQueue()  
  46. {  
  47.        if(!list)  
  48.        {  
  49.               delete[]list;                  //注意数组的删除,为delete []list;  
  50.               list = NULL;  
  51.        }  
  52. }  
  53.    
  54. template<typename Type>  
  55. arrQueue<Type>::arrQueue(const arrQueue<Type>©Queue)  
  56. {  
  57.        maxSize =copyQueue.maxSize;  
  58.        front =copyQueue.front;  
  59.        rear = copyQueue.rear;  
  60.        list = newType[maxSize];            //注意需要自定义大小,容易出错.  
  61.        forint i = 0; i <rear; i++)  
  62.        {  
  63.               list[i] =copyQueue.list[i];  
  64.        }  
  65. }  
  66.    
  67. template<typename Type>  
  68. arrQueue<Type>& arrQueue<Type>::operator=(constarrQueue<Type>& otherQueue)  
  69. {  
  70.        if(this ==&otherQueue)  
  71.        {  
  72.               cout <<"can't copy oneSelf!" << endl;  
  73.               return *this;  
  74.        }  
  75.        else  
  76.        {  
  77.               if(maxSize !=otherQueue.maxSize)  
  78.               {  
  79.                      cout<< "The Size of two Queue are not equal!" << endl;  
  80.                      return*this;  
  81.               }  
  82.               else  
  83.               {  
  84.                      maxSize= otherQueue.maxSize;  
  85.                      front =otherQueue.front;  
  86.                      rear =otherQueue.rear;  
  87.                      for( inti = 0; i < rear; i++)  
  88.                      {  
  89.                             list[i]= otherQueue.list[i];  
  90.                      }//endfor  
  91.                      return*this;  
  92.               }  
  93.        }//end else  
  94. }  
  95.    
  96. template<typename Type>  
  97. void arrQueue<Type>::initializeQueue()  
  98. {  
  99.        destroyQueue();  
  100. }  
  101.    
  102. template<typename Type>  
  103. void arrQueue<Type>::destroyQueue()  
  104. {  
  105.        front = 0;  
  106.        rear = 0;  
  107. }  
  108.    
  109. //栈空的判定标志rear==front[初始]  
  110. template<typename Type>  
  111. bool arrQueue<Type>::isQueueEmpty()  
  112. {  
  113.        return (rear ==front);  
  114. }  
  115.    
  116. //空余1位作为判定位,可以把存储结构想象成环!  
  117. //注意栈满的判定:1.保证空间都被占用;  
  118. //2.保证rear的下一个位置=front即为满。  
  119. template<typename Type>  
  120. bool arrQueue<Type>::isQueueFull()  
  121. {  
  122.        return((rear+1)%maxSize == front);   
  123. }  
  124.    
  125. template<typename Type>  
  126. void arrQueue<Type>::addQueue(const Type& item)  
  127. {  
  128.        if(!isQueueFull())  
  129.        {  
  130.               list[rear] =item;  
  131.               rear =(rear+1)%maxSize;  
  132.               cout << item<< " was added to Queue!" << endl;  
  133.        }  
  134.        else  
  135.        {  
  136.               cout <<"The Queue was already Full!" << endl;  
  137.        }  
  138. }  
  139.    
  140. template<typename Type>  
  141. void arrQueue<Type>::deQueue(Type& deletedItem)  
  142. {  
  143.        if(!isQueueEmpty())  
  144.        {  
  145.               deletedItem =list[front];  
  146.               front =(front+1)%maxSize;                  //注意此处的判定!  
  147.               cout <<deletedItem << " was deleted from Queue!" << endl;  
  148.        }  
  149.        else  
  150.        {  
  151.               cout <<"The Queue was already Empty!" << endl;  
  152.        }  
  153. }  

2.队列采用链表链式存储结构

注意:1)此时的front和rear都变成了指针,front变成了头结点指针,而rear变成了尾节点的指针。2)此处的front和rear类似于链表操作中的first和last。3)入队实现主要在队列尾部实现,需要调整rear指针的指向;而出队操作主要在队头实现,需要调整front指针的指向。

[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 linkedQueue  
  10. {  
  11. public:  
  12.        linkedQueue();  
  13.        ~linkedQueue();  
  14.        linkedQueue(constlinkedQueue<Type>&);  
  15.        linkedQueue&operator=(const linkedQueue<Type>&);  
  16.    
  17.        voidinitializeQueue();  
  18.        void destroyQueue();  
  19.        bool isQueueEmpty()const;  
  20.        bool isQueueFull()const;  
  21.        void addQueue(constType& item);  
  22.        void deQueue(Type&poppedItem);  
  23.        void nodeCount();  
  24.    
  25. private:  
  26.        nodeType<Type>*rear;  
  27.        nodeType<Type>*front;  
  28.        int count;         //统计节点个数  
  29. };  
  30.    
  31. template<typename Type>  
  32. linkedQueue<Type>::linkedQueue()  
  33. {  
  34.        count = 0;  
  35.        front = NULL;  
  36.        rear = NULL;  
  37. }  
  38.    
  39. template<typename Type>  
  40. linkedQueue<Type>::~linkedQueue()  
  41. {  
  42.        while( front != NULL )  
  43.        {  
  44.               nodeType<Type>*tempNode = new nodeType<Type>;  
  45.               tempNode =front;  
  46.               front =front->link;  
  47.    
  48.               deletetempNode;  
  49.        }  
  50.        //注意rear的清空  
  51.        rear = NULL;  
  52. }  
  53.    
  54. template<typename Type>  
  55. linkedQueue<Type>::linkedQueue(constlinkedQueue<Type>& copyQueue)  
  56. {  
  57.        if(copyQueue.front !=NULL)  
  58.        {  
  59.               nodeType<Type>*current;  
  60.               nodeType<Type>*first;  
  61.               nodeType<Type>*newNode;  
  62.    
  63.               front = newnodeType<Type>;  
  64.               front->info= copyQueue.front->info;          //此处的top不能直接用,内存报错!  
  65.               front->link= copyQueue.front->link;  
  66.    
  67.               first =front;                        //first跟进当前链表...  
  68.               current =copyQueue.front->link;      //current跟进copy链表...  
  69.               while( current!= NULL)  
  70.               {  
  71.                      newNode= new nodeType<Type>;  
  72.                      newNode->link= current->link;  
  73.                      newNode->info= current->info;  
  74.    
  75.                      first->link= newNode;  
  76.                      first =newNode;  
  77.                      current= current->link;  
  78.               }//end while  
  79.               rear = current;  
  80.               count =copyQueue.count;  
  81.        }//end if  
  82.        else  
  83.        {  
  84.               front = NULL;  
  85.               rear = NULL;  
  86.               count = 0;  
  87.        }  
  88. }  
  89.    
  90. template<typename Type>  
  91. linkedQueue<Type>& linkedQueue<Type>::operator=(constlinkedQueue<Type>& otherQueue)  
  92. {  
  93.        //1避免自身赋值  
  94.        if(this ==&otherQueue)  
  95.        {  
  96.               cout <<"Can't copy oneself!" << endl;  
  97.               return *this;  
  98.        }  
  99.        //2其他  
  100.        else  
  101.        {  
  102.               if(front !=NULL)  
  103.               {  
  104.                      destroyQueue();  
  105.               }  
  106.               if(otherQueue.front!= NULL)  
  107.               {  
  108.                      nodeType<Type>*current;  
  109.                      nodeType<Type>*first;  
  110.                      nodeType<Type>*newNode;  
  111.    
  112.                      front =new nodeType<Type>;  
  113.                      front->info= otherQueue.front->info;  
  114.                      front->link= otherQueue.front->link;  
  115.                      first =front;                        //first跟进当前链表...  
  116.                      current= otherQueue.front->link;     //current跟进copy链表...  
  117.                      while(current != NULL)  
  118.                      {  
  119.                             newNode= new nodeType<Type>;  
  120.                             newNode->link= current->link;  
  121.                             newNode->info= current->info;  
  122.    
  123.                             first->link= newNode;  
  124.                             first= newNode;  
  125.                             current= current->link;  
  126.                      }//endwhile  
  127.                      rear =current;  
  128.                      count =otherQueue.count;  
  129.               }//end if  
  130.               else  
  131.               {  
  132.                      front =NULL;  
  133.                      rear =NULL;  
  134.                      count =0;  
  135.               }  
  136.               return *this;  
  137.        }  
  138. }  
  139.    
  140. template<typename Type>  
  141. void linkedQueue<Type>::initializeQueue()  
  142. {  
  143.        destroyQueue();  
  144. }  
  145.    
  146. template<typename Type>  
  147. void linkedQueue<Type>::destroyQueue()  
  148. {  
  149.        count = 0;  
  150.        //注意此处的销毁工作:需要循环判定!  
  151.        while(front != NULL)  
  152.        {  
  153.               nodeType<Type>*temp = new nodeType<Type>;  
  154.               temp = front;  
  155.               front =front->link;  
  156.        }  
  157.    
  158.        rear = NULL;  
  159. }  
  160.    
  161. template<typename Type>  
  162. bool linkedQueue<Type>::isQueueEmpty() const  
  163. {  
  164.        return (front ==NULL);  
  165. }  
  166.    
  167. template<typename Type>  
  168. bool linkedQueue<Type>::isQueueFull() const //空间非固定,动态申请!  
  169. {  
  170.        return false;  
  171. }  
  172.    
  173. template<typename Type>  
  174. void linkedQueue<Type>::addQueue(const Type& item)  
  175. {  
  176.        if(!isQueueFull())  
  177.        {  
  178.               nodeType<Type>*newNode = new nodeType<Type>;  
  179.               newNode->info= item;  
  180.               newNode->link= NULL;  
  181.    
  182.               if(front ==NULL)  
  183.               {  
  184.                      front =newNode;  
  185.                      rear =newNode;  
  186.               }  
  187.               else  
  188.               {  
  189.                      rear->link= newNode;  
  190.                      rear =newNode;  
  191.               }  
  192.               count++;  
  193.               cout <<item << " was pushed!" << endl;  
  194.        }  
  195. }  
  196.    
  197. template<typename Type>  
  198. void linkedQueue<Type>::deQueue(Type& deletedItem)  
  199. {  
  200.        if(!isQueueEmpty())  
  201.        {  
  202.               nodeType<Type>*temp = new nodeType<Type>;  
  203.               temp = front;  
  204.               deletedItem =front->info;  
  205.               front =front->link;  
  206.    
  207.               count--;  
  208.               cout <<deletedItem << " was popped!" << endl;  
  209.               delete temp;  
  210.        }  
  211. }  
  212.    
  213. template<typename Type>  
  214. void linkedQueue<Type>::nodeCount()  
  215. {  
  216.        cout <<"nodeCount = " << count << endl;  
  217. }  
  218.    

3.用栈实现队列

注意栈是先进后出,而用两个栈:栈1先进后出,栈2在栈1的基础上先进后出,就能实现了先进先出。

注意:入队addtoQueue要保证将元素放入到栈1中;而对于出队deQueue要保证将栈1的全部元素出栈pop,然后再全部入栈2,最后执行出栈2操作即可。

[cpp]  view plain copy
  1. #include"linkedStack.h"  
  2. template<typename Type>  
  3. class stackedQueue  
  4. {  
  5. public:  
  6.        stackedQueue();  
  7.        ~stackedQueue();  
  8.    
  9.        void addQueue(Type item);  
  10.        void deQueue(Type deletedItem);  
  11.         
  12.        bool isQueueEmpty();  
  13.        bool isQueueFull();  
  14.    
  15. private:  
  16.        nodeType<Type>* front;  
  17.        nodeType<Type>* rear;  
  18.        linkedStack<Type>* firstStack;  
  19.        linkedStack<Type>* secondStack;  
  20.        int nodeCnt;    //记录节点个数  
  21. };  
  22.    
  23. template<typename Type>  
  24. stackedQueue<Type>::stackedQueue()  
  25. {  
  26.        front = NULL;  
  27.        rear = NULL;  
  28.     nodeCnt = 0;  
  29.         
  30.        firstStack = new linkedStack<Type>;  
  31.        secondStack = new linkedStack<Type>;  
  32. }  
  33.    
  34. template<typename Type>  
  35. stackedQueue<Type>::~stackedQueue()  
  36. {  
  37.        while(front != NULL)  
  38.        {  
  39.               nodeType<Type>* temp;  
  40.               temp = front;  
  41.               front = front->link;  
  42.        }  
  43.        rear = NULL;  
  44.        if(firstStack != NULL)  
  45.        {  
  46.               delete firstStack;  
  47.               firstStack = NULL;  
  48.        }  
  49.        if(secondStack != NULL)  
  50.        {  
  51.               delete secondStack;  
  52.               secondStack = NULL;  
  53.        }  
  54. }  
  55.    
  56. template<typename Type>  
  57. voidstackedQueue<Type>::addQueue(Type item)  
  58. {  
  59.        if(!isQueueFull())  
  60.        {  
  61.               nodeCnt++;  
  62.               firstStack->push(item);        //单个入栈1  
  63.               cout << item << " was added toQueue!" << endl;  
  64.        }  
  65. }  
  66.    
  67. template<typename Type>  
  68. voidstackedQueue<Type>::deQueue(Type deletedItem)  
  69. {  
  70.        if(!isQueueEmpty())  
  71.        {  
  72.               while(!firstStack->isStackEmpty())  
  73.               {  
  74.                      firstStack->pop(deletedItem);              //全部出栈1  
  75.                      if(!firstStack->isStackFull())  
  76.                      {  
  77.                             secondStack->push(deletedItem);       //全部入栈2  
  78.                      }  
  79.               }  
  80.               if(!secondStack->isStackEmpty())  
  81.               {  
  82.                      secondStack->pop(deletedItem);            //单个出栈2  
  83.               }  
  84.               cout << deletedItem << " was out ofQueue!" << endl;  
  85.               nodeCnt--;  
  86.        }  
  87. }  
  88.    
  89. template<typename Type>  
  90. boolstackedQueue<Type>::isQueueEmpty()  
  91. {  
  92.        return (nodeCnt == 0);  
  93. }  
  94.    
  95. template<typename Type>  
  96. boolstackedQueue<Type>::isQueueFull()  
  97. {  
  98.        return false;  
  99. }  

你可能感兴趣的:(数据结构面试之四——队列的常见操作)