[轉]Queue基本操做

(java版)html

  1. import java.util.LinkedList;     
  2. //單向隊列     
  3. public class Queue {     
  4.     public Queue() {     
  5.     }     
  6.     private LinkedList list = new LinkedList();     
  7.     public void put(Object v) {     
  8.         list.addFirst(v);     
  9.     }     
  10.     public Object get() {     
  11.         return list.removeLast();     
  12.     }     
  13.     public boolean isEmpty() {     
  14.         return list.isEmpty();     
  15.     }     
  16. }   
  17.    
  18.   
  19. import java.util.Collection;     
  20. import java.util.Iterator;     
  21. import java.util.LinkedList;     
  22. // 雙向隊列     
  23. public class DQueue implements Collection {     
  24.     private LinkedList lists;     
  25.     public DQueue() {     
  26.         lists = new LinkedList();     
  27.     }     
  28.     public void put_front(Object v) {     
  29.         lists.addFirst(v);     
  30.     }     
  31.     public void put_back(Object v) {     
  32.         lists.addLast(v);     
  33.     }     
  34.     public Object get_front() {     
  35.         return lists.removeFirst();     
  36.     }     
  37.     public Object get_Back() {     
  38.         return lists.removeLast();     
  39.     }     
  40.     public boolean isEmpty() {     
  41.         return lists.isEmpty();     
  42.     }     
  43.     public int size() {     
  44.         return lists.size();     
  45.     }     
  46.     public boolean contains(Object o) {     
  47.         return lists.contains(o);     
  48.     }     
  49.     public Iterator iterator() {     
  50.         return lists.iterator();     
  51.     }     
  52.     public Object[] toArray() {     
  53.         return lists.toArray();     
  54.     }     
  55.     public Object[] toArray(Object a[]) {     
  56.         return lists.toArray(a);     
  57.     }     
  58.     public boolean add(Object o) {     
  59.         lists.addLast(o);     
  60.         return true;     
  61.     }     
  62.     public boolean remove(Object o) {     
  63.         return lists.remove(o);     
  64.     }     
  65.     public boolean containsAll(Collection c) {     
  66.         return lists.containsAll(c);     
  67.     }     
  68.     public boolean addAll(Collection c) {     
  69.         return lists.addAll(c);     
  70.     }     
  71.     public boolean removeAll(Collection c) {     
  72.         return lists.removeAll(c);     
  73.     }     
  74.     public boolean retainAll(Collection c) {     
  75.         return lists.retainAll(c);     
  76.     }     
  77.     public void clear() {     
  78.         lists.clear();     
  79.     }     
  80. }   

 

 

 

(C版)前端

隊列也是表,使用隊列時,插入在一端進行,而刪除在另外一端進行。java

經常使用的操做:node

[cpp]  view plain copy
 
  1. /**是否爲空隊列**/  
  2.   
  3. int isEmpty(Queue q)  
  4.   
  5. /**隊列是否已滿**/  
  6.   
  7. int isFull(Queue q)  
  8.   
  9. /**實現循環隊列,重置rear或者front**/  
  10.   
  11. int circularQ(int index,Queue q)  
  12.   
  13. /*入列*/  
  14.   
  15. void enQueue(Queue q,int item)  
  16.   
  17. /*出列*/  
  18.   
  19. int deQueue(Queue q)  
  20.   
  21. /**取隊列頭元素**/  
  22.   
  23. int front(Queue q)  

 

Queue.cpython

 

[cpp]  view plain copy
 
    1. #include <stdio.h>  
    2. #include <stdlib.h>  
    3.   
    4. typedef struct QueueRec{  
    5.     int front;  
    6.     int rear;  
    7.     int size;//隊列元素個數  
    8.     int capacity;//隊列大小  
    9.     int *Array;  
    10. } lqueue,*Queue;  
    11.   
    12. int isEmpty(Queue q){  
    13.     return q->size==0;  
    14. }  
    15.   
    16. int isFull(Queue q){  
    17.     return q->size==q->capacity;  
    18. }  
    19.   
    20. Queue createQueue(int capacity){  
    21.     Queue queue;  
    22.     queue = (Queue)malloc(sizeof(lqueue));  
    23.     if(queue==NULL){  
    24.         return NULL;  
    25.     }  
    26.     queue->Array = malloc(sizeof(int)*capacity);  
    27.     if(queue->Array == NULL ){  
    28.         return NULL;  
    29.     }  
    30.     queue->capacity = capacity;  
    31.     queue->size = 0;  
    32.     queue->front = 0;  
    33.     queue->rear = -1;  
    34.     return queue;  
    35. }  
    36.   
    37. void makEmpty(Queue q){  
    38.     q->size = 0;  
    39.     q->rear = -1;  
    40.     q->front = 0;  
    41. }  
    42.   
    43. void disPoseQueue(Queue q){  
    44.     if(q!=NULL){  
    45.         free(q);      
    46.     }  
    47. }  
    48.   
    49. /**這個方法實現循環隊列,當rear到達尾端(入列),或者front到達尾端(出列),它又回到開頭**/  
    50. int circularQ(int index,Queue q){  
    51.     if(++index > q->capacity){  
    52.         return 0;  
    53.     }  
    54.     return index;  
    55. }  
    56.   
    57. /*入列*/  
    58. void enQueue(Queue q,int item){  
    59.     if(isFull(q)){  
    60.         printf("Queue is Full\n");  
    61.     } else {  
    62.         q->size ++;  
    63.         q->rear = circularQ(q->rear,q);  
    64.         q->Array[q->rear] = item;  
    65.     }  
    66. }  
    67.   
    68. /*出列*/  
    69. int deQueue(Queue q){  
    70.     int temp;  
    71.     if(isEmpty(q)){  
    72.         printf("queue is Empty\n");  
    73.     } else {  
    74.         q->size --;  
    75.         temp = q->Array[q->front];  
    76.         q->front = circularQ(q->front,q);  
    77.     }  
    78.     return temp;  
    79. }  
    80.   
    81. /**取隊列頭元素**/  
    82. int front(Queue q){  
    83.     return q->Array[q->front];  
    84. }  
    85.   
    86. int main(void){  
    87.     Queue q = createQueue(5);  
    88.     enQueue(q,1);  
    89.     enQueue(q,2);  
    90.     enQueue(q,3);  
    91.     enQueue(q,4);  
    92.     enQueue(q,5);  
    93.     enQueue(q,6);  
    94.     printf("%d\n",front(q));  
    95.     printf("%d\n",deQueue(q));  
    96.     printf("%d\n",deQueue(q));  
    97.     enQueue(q,7);  
    98.     printf("%d\n",front(q));  
    99.     disPoseQueue(q);  
    100.     return -1;  
    101. }  
    102. 小操做:
    103. 在java5中新增長了java.util.Queue接口,用以支持隊列的常見操做。該接口擴展了java.util.Collection接口。
      Queue使用時要儘可能避免Collection的add()和remove()方法,而是要使用offer()來加入元素,使用poll()來獲取並移出元素。它們的優
      點是經過返回值能夠判斷成功與否,add()和remove()方法在失敗的時候會拋出異常。 若是要使用前端而不移出該元素,使用
      element()或者peek()方法。
      值得注意的是LinkedList類實現了Queue接口,所以咱們能夠把LinkedList當成Queue來用。
      [java]  view plain copy
       
      1. 小例子:   
      2.   
      3. /** 
      4.  * 
      5.  * @author Zang XT 
      6.  */  
      7. import java.util.Queue;  
      8. import java.util.LinkedList;  
      9. public class TestQueue {  
      10.     public static void main(String[] args) {  
      11.         Queue<String> queue = new LinkedList<String>();  
      12.         queue.offer("Hello");  
      13.         queue.offer("World!");  
      14.         queue.offer("你好!");  
      15.         System.out.println(queue.size());  
      16.         String str;  
      17.         while((str=queue.poll())!=null){  
      18.             System.out.print(str);  
      19.         }  
      20.         System.out.println();  
      21.         System.out.println(queue.size());  
      22.     }  
      23. }  
      24.  
      25. (java版)
      26. Queue接口與List、Set同一級別,都是繼承了Collection接口。LinkedList實現了Queue接 口。Queue接口窄化了對LinkedList的方法的訪問權限(即在方法中的參數類型若是是Queue時,就徹底只能訪問Queue接口所定義的方法 了,而不能直接訪問 LinkedList的非Queue的方法),以使得只有恰當的方法纔可使用。BlockingQueue 繼承了Queue接口。ios

         

        隊列是一種數據結構.它有兩個基本操做:在隊列尾部加人一個元素,和從隊列頭部移除一個元素就是說,隊列以一種先進先出的方式管理數據,若是你試圖向一個 已經滿了的阻塞隊列中添加一個元素或者是從一個空的阻塞隊列中移除一個元索,將致使線程阻塞.在多線程進行合做時,阻塞隊列是頗有用的工具。工做者線程可 以按期地把中間結果存到阻塞隊列中而其餘工做者線線程把中間結果取出並在未來修改它們。隊列會自動平衡負載。若是第一個線程集運行得比第二個慢,則第二個 線程集在等待結果時就會阻塞。若是第一個線程集運行得快,那麼它將等待第二個線程集遇上來。下表顯示了jdk1.5中的阻塞隊列的操做:數組

         

        add        增長一個元索                     若是隊列已滿,則拋出一個IIIegaISlabEepeplian異常
        remove   移除並返回隊列頭部的元素    若是隊列爲空,則拋出一個NoSuchElementException異常
        element  返回隊列頭部的元素             若是隊列爲空,則拋出一個NoSuchElementException異常
        offer       添加一個元素並返回true       若是隊列已滿,則返回false
        poll         移除並返問隊列頭部的元素    若是隊列爲空,則返回null
        peek       返回隊列頭部的元素             若是隊列爲空,則返回null
        put         添加一個元素                      若是隊列滿,則阻塞
        take        移除並返回隊列頭部的元素     若是隊列爲空,則阻塞數據結構

         

        remove、element、offer 、poll、peek 實際上是屬於Queue接口。 多線程

         

        阻塞隊列的操做能夠根據它們的響應方式分爲如下三類:aad、removee和element操做在你試圖爲一個已滿的隊列增長元素或從空隊列取得元素時 拋出異常。固然,在多線程程序中,隊列在任什麼時候間均可能變成滿的或空的,因此你可能想使用offer、poll、peek方法。這些方法在沒法完成任務時 只是給出一個出錯示而不會拋出異常。app

         

        注意:poll和peek方法出錯進返回null。所以,向隊列中插入null值是不合法的。

         

        還有帶超時的offer和poll方法變種,例如,下面的調用:
        boolean success = q.offer(x,100,TimeUnit.MILLISECONDS);
        嘗試在100毫秒內向隊列尾部插入一個元素。若是成功,當即返回true;不然,當到達超時進,返回false。一樣地,調用:
        Object head = q.poll(100, TimeUnit.MILLISECONDS);
        若是在100毫秒內成功地移除了隊列頭元素,則當即返回頭元素;不然在到達超時時,返回null。

         

        最後,咱們有阻塞操做put和take。put方法在隊列滿時阻塞,take方法在隊列空時阻塞。

         

        java.ulil.concurrent包提供了阻塞隊列的4個變種。默認狀況下,LinkedBlockingQueue的容量是沒有上限的(說的不許確,在不指定時容量爲Integer.MAX_VALUE,不要然的話在put時怎麼會受阻呢),可是也能夠選擇指定其最大容量,它是基於鏈表的隊列,此隊列按 FIFO(先進先出)排序元素。


        ArrayBlockingQueue在構造時須要指定容量, 並能夠選擇是否須要公平性,若是公平參數被設置true,等待時間最長的線程會優先獲得處理(其實就是經過將ReentrantLock設置爲true來 達到這種公平性的:即等待時間最長的線程會先操做)。一般,公平性會使你在性能上付出代價,只有在的確很是須要的時候再使用它。它是基於數組的阻塞循環隊 列,此隊列按 FIFO(先進先出)原則對元素進行排序。


        PriorityBlockingQueue是一個帶優先級的 隊列,而不是先進先出隊列。元素按優先級順序被移除,該隊列也沒有上限(看了一下源碼,PriorityBlockingQueue是對 PriorityQueue的再次包裝,是基於堆數據結構的,而PriorityQueue是沒有容量限制的,與ArrayList同樣,因此在優先阻塞 隊列上put時是不會受阻的。雖然此隊列邏輯上是無界的,可是因爲資源被耗盡,因此試圖執行添加操做可能會致使 OutOfMemoryError),可是若是隊列爲空,那麼取元素的操做take就會阻塞,因此它的檢索操做take是受阻的。另外,往入該隊列中的元 素要具備比較能力。


        最後,DelayQueue(基於PriorityQueue來實現的)是一個存放Delayed 元素的無界阻塞隊列,只有在延遲期滿時才能從中提取元素。該隊列的頭部是延遲期滿後保存時間最長的 Delayed 元素。若是延遲都尚未期滿,則隊列沒有頭部,而且poll將返回null。當一個元素的 getDelay(TimeUnit.NANOSECONDS) 方法返回一個小於或等於零的值時,則出現期滿,poll就以移除這個元素了。此隊列不容許使用 null 元素。 下面是延遲接口:

        Java代碼
        1. public interface Delayed extends Comparable {  
        2.      long getDelay(TimeUnit unit);  
        3. }  

        放入DelayQueue的元素還將要實現compareTo方法,DelayQueue使用這個來爲元素排序。

         

        下面的實例展現瞭如何使用阻塞隊列來控制線程集。程序在一個目錄及它的全部子目錄下搜索全部文件,打印出包含指定關鍵字的文件列表。從下面實例能夠看出,使用阻塞隊列兩個顯著的好處就是:多線程操做共同的隊列時不須要額外的同步,另外就是隊列會自動平衡負載,即那邊(生產與消費兩邊)處理快了就會被阻塞掉,從而減小兩邊的處理速度差距。下面是具體實現:

        Java代碼
        1. public class BlockingQueueTest {  
        2.     public static void main(String[] args) {  
        3.         Scanner in = new Scanner(System.in);  
        4.         System.out.print("Enter base directory (e.g. /usr/local/jdk5.0/src): ");  
        5.         String directory = in.nextLine();  
        6.         System.out.print("Enter keyword (e.g. volatile): ");  
        7.         String keyword = in.nextLine();  
        8.   
        9.         final int FILE_QUEUE_SIZE = 10;// 阻塞隊列大小  
        10.         final int SEARCH_THREADS = 100;// 關鍵字搜索線程個數  
        11.   
        12.         // 基於ArrayBlockingQueue的阻塞隊列  
        13.         BlockingQueue queue = new ArrayBlockingQueue(  
        14.                 FILE_QUEUE_SIZE);  
        15.   
        16.         //只啓動一個線程來搜索目錄  
        17.         FileEnumerationTask enumerator = new FileEnumerationTask(queue,  
        18.                 new File(directory));  
        19.         new Thread(enumerator).start();  
        20.           
        21.         //啓動100個線程用來在文件中搜索指定的關鍵字  
        22.         for (int i = 1; i <= SEARCH_THREADS; i++)  
        23.             new Thread(new SearchTask(queue, keyword)).start();  
        24.     }  
        25. }  
        26. class FileEnumerationTask implements Runnable {  
        27.     //啞元文件對象,放在阻塞隊列最後,用來標示文件已被遍歷完  
        28.     public static File DUMMY = new File("");  
        29.   
        30.     private BlockingQueue queue;  
        31.     private File startingDirectory;  
        32.   
        33.     public FileEnumerationTask(BlockingQueue queue, File startingDirectory) {  
        34.         this.queue = queue;  
        35.         this.startingDirectory = startingDirectory;  
        36.     }  
        37.   
        38.     public void run() {  
        39.         try {  
        40.             enumerate(startingDirectory);  
        41.             queue.put(DUMMY);//執行到這裏說明指定的目錄下文件已被遍歷完  
        42.         } catch (InterruptedException e) {  
        43.         }  
        44.     }  
        45.   
        46.     // 將指定目錄下的全部文件以File對象的形式放入阻塞隊列中  
        47.     public void enumerate(File directory) throws InterruptedException {  
        48.         File[] files = directory.listFiles();  
        49.         for (File file : files) {  
        50.             if (file.isDirectory())  
        51.                 enumerate(file);  
        52.             else  
        53.                 //將元素放入隊尾,若是隊列滿,則阻塞  
        54.                 queue.put(file);  
        55.         }  
        56.     }  
        57. }  
        58. class SearchTask implements Runnable {  
        59.     private BlockingQueue queue;  
        60.     private String keyword;  
        61.   
        62.     public SearchTask(BlockingQueue queue, String keyword) {  
        63.         this.queue = queue;  
        64.         this.keyword = keyword;  
        65.     }  
        66.   
        67.     public void run() {  
        68.         try {  
        69.             boolean done = false;  
        70.             while (!done) {  
        71.                 //取出隊首元素,若是隊列爲空,則阻塞  
        72.                 File file = queue.take();  
        73.                 if (file == FileEnumerationTask.DUMMY) {  
        74.                     //取出來後從新放入,好讓其餘線程讀到它時也很快的結束  
        75.                     queue.put(file);  
        76.                     done = true;  
        77.                 } else  
        78.                     search(file);  
        79.             }  
        80.         } catch (IOException e) {  
        81.             e.printStackTrace();  
        82.         } catch (InterruptedException e) {  
        83.         }  
        84.     }  
        85.     public void search(File file) throws IOException {  
        86.         Scanner in = new Scanner(new FileInputStream(file));  
        87.         int lineNumber = 0;  
        88.         while (in.hasNextLine()) {  
        89.             lineNumber++;  
        90.             String line = in.nextLine();  
        91.             if (line.contains(keyword))  
        92.                 System.out.printf("%s:%d:%s%n", file.getPath(), lineNumber,  
        93.                         line);  
        94.         }  
        95.         in.close();  
        96.     }  
        97. }
        98. java多線程和queue的使用
        99. /*******公用的一個報警配置類*******************************************************/

          public class AlarmConfig {//AlarmConfig 報警配置類

           public static final boolean FIND_ENABLE = true;//FINDENABLE 啓用檢測
           public static final boolean FIND_UNABLE = false;//FINDUNABLE 關閉檢測  當發生線程開啓時,偵測線程是關閉的。

           public static boolean ReceiveFind = FIND_UNABLE ;//ReceiveFind 接收檢測    初始狀態是關閉的

           public static QueueArray queueArray =  new  QueueArray();//QueueArray 類裏放這一個循環隊列

           public AlarmConfig() {


           }

          }

          /***********循環隊列類****************************************************/

          public class QueueArray {//隊列

           private Object[] obj;   //初始化儲存空間

           private  int front;     //頭指針,若隊列不爲空,指向隊列頭元素

           private  int rear;      //尾指針,若隊列不爲空,指向隊列尾元素的下一個位置


           public QueueArray() {
            this(10);
           }

           public QueueArray(int size){
            //隊列進行初始化
                  obj=new Object[size];
            front=0;
            rear=0;
           }

           public Object dequeue(){//出隊

            if(rear==front){
             return null;
            }

            Object ob=obj[front];

            front=(front+1)%obj.length;

            return ob;
           }

           public boolean enqueue(Object obje){//入隊

            if((rear+1)%obj.length==front){

             return false;

            }

            obj[rear]=obje;

            rear=(rear+1)%obj.length;

            return true;
           }

           public static void main(String[] args) {
                QueueArray d=new QueueArray(10);
                for(int i=0;i<=20;i++){
                        System.out.println(i+"  "+ d.enqueue(i));
                    if(i>8){
                           System.out.println(i+"  "+d.dequeue());
                       }
                }
            }

          }

          /*********偵測線程****************************************************************/

          public class MonitorThread implements Runnable{   //MonitorThread 是 偵測線程

           private Thread thread;  // 分配新的 線程 對象。

           private boolean stop = true;

           public void strat() {//開啓方法

            if (stop) {//若是stop等於true 那麼就給stop賦值false,而後開啓一個線程

             thread = new Thread(this);// this 是其 run 方法被調用的對象

             stop = false;

             thread.start(); // 開始一個線程

            }

           }

           public void stop() {//中止方法

            stop = true;//給stop 賦值爲true

            thread = null;
           } 

           public void run() {

            while (!stop) {

             if (AlarmConfig.ReceiveFind) {

              Object num=AlarmConfig.queueArray.dequeue();
              System.out.println("檢測接收:"+num);
              look(num);
              AlarmConfig.ReceiveFind = AlarmConfig.FIND_UNABLE;

             }

             try {
              Thread.sleep(100);
             } catch (InterruptedException e) {
              // TODO Auto-generated catch block
              e.printStackTrace();
             }

            }

           }

           public void look(Object ob){
             if(ob.equals(2)||ob.equals(12)){
              System.out.println("報警!  發現錯誤報告! ======");
             }
           }

          }

          /********發生器線程********************************************************************/


          public class ThreadA implements Runnable {

           private Thread thread;// 分配新的 線程 對象。

           private boolean stop = true;

           private int num = 1;


           public ThreadA() {// 無參的構造方法
                  //自動生成構造函數存根
           }

           public void strat() {//開啓方法

            if (stop) {//若是stop等於true 那麼就給stop賦值false,而後開啓一個線程

             thread = new Thread(this);// this 是其 run 方法被調用的對象

             stop = false;

             thread.start(); // 開始一個線程
             System.out.println("**當前stop爲*******" + stop);
            }

           }

           public void stop() {//中止方法

            stop = true;//給stop 賦值爲true
            System.out.println(" stop true");
            thread = null;
           }


           public void run() {

            System.out.println("*test**");

            while (!stop) {

             if (!AlarmConfig.ReceiveFind) {

              System.out.println(num + " 發生器: "+ AlarmConfig.queueArray.enqueue(num));

              AlarmConfig.ReceiveFind = AlarmConfig.FIND_ENABLE;

              num++;
             }

             try {
              Thread.sleep(100);
             } catch (InterruptedException e) {
              // TODO Auto-generated catch block
              e.printStackTrace();
             }

            }

           }

          }

          /*************測試類******************************************************/

          public class TestMainThread {

           public TestMainThread() {
            // TODO Auto-generated constructor stub
           }


           public static void main(String[] args) {

            ThreadA treadA = new ThreadA();
            treadA.strat();
            //treadA.stop();

            MonitorThread monitorThread=new MonitorThread();
            monitorThread.strat();
            //monitorThread.stop();

           }

          }

        100. ===================================================
        101. (C版)
        102. 實驗要求:

          (1)編寫連接隊列的基本操做函數

          1.進隊函數 EnQueue(LinkQueue *Q,QElemType e)

          2.出隊函數 ,隊空 DeQueue(LinkQueue *Q,QElemType e)

          3.輸出隊列中元素  OutputQueue(LinkQueue *Q)

           

          (2)調用上述函數實現下列操做,操做步驟以下

          1.調用進隊函數創建一個隊列

          2.讀取隊列中的第一個元素

          2.從隊列中刪除元素

          4.輸出隊列中的全部元素

           

          (3)編寫環形隊列的基本操做函數

          1.進隊函數 EnQueue(SqQueue *Q,QElemType e)

          2.出隊函數 ,隊空 DeQueue(SqQueue *Q,QElemType e)

          3.輸出隊列中元素  OutputQueue(SqQueue *Q)

          (4)調用上述函數實現下列操做,操做步驟以下

          1.調用進隊函數創建一個隊列

          2.讀取隊列中的第一個元素

          2.從隊列中刪除元素

          4.輸出隊列中的全部元素

           

           

           

           

           

           

           

           

          1.連接隊列:

          #include<stdio.h>

          #include<malloc.h>

          typedef struct node

           {int data;

            struct node *next;

            };

          typedef struct 

          {struct node *front;

           struct node *rear;

          }LinkQueue;

           

          InitQueue(LinkQueue *Q)

          { Q->front=(struct node *)malloc(sizeof( struct node));

            Q->rear=Q->front;

            Q->front->next=NULL;

          }

           

           EnQueue(LinkQueue *Q,int e)

          {struct node *p;

           p=(struct node *)malloc(sizeof(struct node ));

           p->data=e;

           p->next=NULL;

           Q->rear->next=p;

           Q->rear=p; 

          }

           

           DeQueue(LinkQueue *Q,int e)

          { struct node *p;

            if(Q->front==Q->rear)

          return 0;

           

           else{

                  p=Q->front->next;

                  Q->front->next=p->next;

                  if(p->next=NULL)Q->rear=Q->front;

                  return(p->data);

                  free(p);

            }

          }

           

          OutputQueue(LinkQueue *Q)

          { struct node *p;

           p=Q->front->next;

           while(p!=NULL)

           { printf("%d ",p->data);

             p=p->next;

           }

          }

           

          GetFront(LinkQueue *Q)

          {  struct node *p;

             p=Q->front->next;

             printf("%d",p->data);

          }

           

           

          void main()

          { LinkQueue s;

            int i,max,e,item;

            InitQueue(&s);

            printf("put a max:");

            scanf("%d",&max);

            printf("shu ru yuan su");

            for(i=0;i<max;i++){ 

                scanf("%d",&e);

                EnQueue(&s,e);}

            OutputQueue(&s);

            printf("\n");

            printf("di yi ge yuan su wei:");

            GetFront(&s);

            printf("\n");

            printf("shu ru shan chu yuan su :");

            scanf("%d",&item);

            DeQueue(&s,item);

            OutputQueue(&s);

            printf("\n");

          }

           

           

           

           

           

           

           

          2.環形隊列:

          #define MAXQSIZE 100

          #include<stdio.h>

          #include<malloc.h>

          typedef struct{

           int *base;

           int front;

           int rear;

          }SqQueue;

           

          InitQueue(SqQueue *Q)

          { Q->base=(int *)malloc(MAXQSIZE * sizeof(int));

            if(!Q->base)exit(1);

            Q->front=Q->rear=0;

          }

           

          EnQueue(SqQueue *Q,int e)

          { Q->base[Q->rear]=e;

            Q->rear=(Q->rear+1)%MAXQSIZE;

          }

           

          DeQueue(SqQueue *Q,int *e)

          { if(Q->front==Q->rear)return 0;

            e=Q->base[Q->front];

            Q->front=(Q->front+1)%MAXQSIZE;

          }

           

          GetFront(SqQueue *Q)

          { if(Q->front==Q->rear)return 0;

            else printf("%d",Q->base[(Q->front)%MAXQSIZE]);

          }

           

          OutputQueue(SqQueue *Q)

          { int i;

            i=Q->front;

            if(!(Q->front==Q->rear))

            {

            while((i%MAXQSIZE)!=Q->rear)

             { printf("%d ",Q->base[i%MAXQSIZE]);

                i++;

             }

            }

           

          }

           

           

          void main()

          { SqQueue *s;

            int i,max,e,item;

            InitQueue(&s);

            printf("put a max:");

            scanf("%d",&max);

            printf("shu ru yuan su :");

            for(i=0;i<max;i++){ 

                scanf("%d",&e);

                EnQueue(&s,e);}

            OutputQueue(&s);

            printf("\n");

            printf("di yi ge yuan su wei :");

            GetFront(&s);

            printf("\n");

            printf("shu ru shan chu yuan su:");

            scanf("%d",&item);

            DeQueue(&s,item);

            OutputQueue(&s);

          }

        103. ===============================================================
        104. (C版循環隊列)
        105. #include<iostream.h>

          #include<malloc.h>

          #include<stdlib.h>

          #define  MAXSIZE   100  

          #define TRUE 1

          #define FALSE 0

          typedef int DataType;

          typedef  struct

          {

            DataType   data[MAXSIZE]; 

            int front; //頭指針指示器

            int rear;  //爲指針指示器

          }SeqQueue;

           

          //初始化操做

          void InitQueue(SeqQueue *Q)

          {//將*Q初始化爲一個空的循環隊列

              Q->front=Q->rear=0;

          }

           

          //判斷隊列是否爲空或滿

          void IsEmpty_full(SeqQueue *Q)

          {

              if(Q->front==Q->rear)

                  cout<<"該隊列爲空"<<endl;

              else if((Q->rear+1)%MAXSIZE==Q->front)

                  cout<<"該隊列爲滿"<<endl;

              else

                  cout<<"該隊列既不爲空也不爲滿"<<endl;

          }

           

          //入隊操做

          int EnterQueue(SeqQueue *Q,DataType x)

          {//將元素x入隊

              if((Q->rear+1)%MAXSIZE==Q->front)  //隊列已經滿了

                  return(FALSE);

              Q->data[Q->rear]=x;

              Q->rear=(Q->rear+1)%MAXSIZE; //從新設置隊尾指針

              return(TRUE); //操做成功

          }

           

          //出隊操做

          int DeleteQueue(SeqQueue *Q,DataType *x)

          {//刪除隊列的隊頭元素,用x返回其值

              if(Q->front==Q->rear) //隊列爲空

                  return(FALSE);

              *x=Q->data[Q->front];

              Q->front=(Q->front+1)%MAXSIZE;  //從新設置隊頭指針

              return(TRUE);  //操做成功

          }

           

          //清空元素

          void ClearQueue_Sq(SeqQueue &Q)

          {

              Q.front=Q.rear=0;

          }

           

          //構造隊列,數據元素由鍵盤輸入

          void CreateQueue_Sq(SeqQueue &Q)

           

          {

              DataType temp;

              cout<<"輸入數據元素(按-1結束)"<<endl;

              cin>>temp;

              while(temp!=-1)

              {

                  if((Q.rear+1)%MAXSIZE == Q.front)  cout<<"隊列已經滿了";

                  else

                  {

                      Q.data[Q.rear]=temp;

                      Q.rear=(Q.rear+1)%MAXSIZE;

                      cin>>temp;

                  }

              }

          }

           

          //隊列的長度

          int QueueLength_Sq(SeqQueue Q)

          {

              return (Q.rear-Q.front+MAXSIZE) % MAXSIZE;

          }

           

          //由頭到尾依次輸出隊列的數據元素

          void OutputQueue_Sq(SeqQueue Q)

          {

              if(Q.front==Q.rear) cout<<"空隊列,沒有元素"<<endl;

              else

              {

                  cout<<"該循環隊列各元素依次爲:";

                  for(int k=0; k<=QueueLength_Sq(Q)-1; k++)

                      cout<<Q.data[(Q.front+k)%MAXSIZE]<<"  ";

                  cout<<endl;

              }

          }

           

          void main()

          {

             int flag=1,select;

             cout<<"                         ☆☆☆☆循環隊列的基本操做☆☆☆☆"<<endl;

             cout<<"  ☆1.請輸入循環隊列元素:☆  "<<endl;

             cout<<"  ☆2.判斷隊列是否爲空或是否爲滿☆"<<endl;

             cout<<"  ☆3.當前隊頭元素出隊並將其輸出循環隊列的各元素☆  "<<endl;

             cout<<"  ☆4.將x入隊並輸出循環隊列的各元素☆  "<<endl;

             cout<<"  ☆5.當前循環隊列的長度☆  "<<endl;

             cout<<"  ☆6.清空隊列☆  "<<endl;

             cout<<"  ☆7.退出☆  "<<endl;

            

          while(flag)

          {

              cout<<"請選擇: ";

              cin>>select;

              SeqQueue Q;

              int x,a,e;

              switch(select)

              {

              case 1:

                  InitQueue(&Q);

                  CreateQueue_Sq(Q);

                  OutputQueue_Sq(Q);

                  break;

                  cout<<"請選擇: ";

              case 2:

                  IsEmpty_full(&Q);

                  break;

                  cout<<"請選擇: ";

              case 3:

                  DeleteQueue(&Q,&a);

                  OutputQueue_Sq(Q);

                  break;

                  cout<<"請選擇: ";

              case 4:

                  cout<<"請輸入入隊的元素x:";

                  cin>>x;

                  EnterQueue(&Q,x);

                  OutputQueue_Sq(Q);

                  break;

                  cout<<"請選擇: ";

              case 5:

                  cout<<"當前循環隊列的長度是:"<<(Q.rear-Q.front+MAXSIZE) % MAXSIZE<<endl;

                  break;

                  cout<<"請選擇: ";

              case 6:

                  ClearQueue_Sq(Q);

                  cout<<"該循環隊列已清空, ";

                  break;

              case 7:

                  flag=0;

                  break;

              }

          }

          }

        106. =============================================
        107. (C版之基本操做)
        108. 隊列是先進先出的數據結構,出隊的一端叫隊首,入隊的一端叫隊尾,就像是平常生活中排隊買火車票同樣,下面是隊列的基本操做

          #include <stdio.h>
          #include <string.h>
          #include <stdlib.h>

          typedef int QElemType;

          typedef struct QNode
          {
              QElemType data;
              struct QNode *next;
          }QNode,*QueuePtr;

          typedef struct
          {
              QueuePtr front;
              QueuePtr rear;
          }LinkQueue;

          int InitQueue(LinkQueue *Q);
          int DestroyQueue(LinkQueue *Q);
          int ClearQueue(LinkQueue *Q);
          int QueueEmpty(LinkQueue Q);
          int QueueLength(LinkQueue Q);
          int GetHead(LinkQueue Q,QElemType *e);
          int InsertQueue(LinkQueue *Q,QElemType e);
          int DelQueue(LinkQueue *Q,QElemType *e);
          int PrintQueue(LinkQueue Q);


          int InitQueue(LinkQueue *Q)
          {
              Q->front = Q->rear = (QueuePtr )malloc(sizeof(QNode));
              if(!Q->front)
              {
                  perror("malloc error\n");
                  return -1;
              }
              Q->front->next = NULL;
              Q->front->data = 0;
              return 0;
          }
          int DestroyQueue(LinkQueue *Q)
          {
              while(Q->front)
              {
                  Q->rear = Q->front->next;
                  free(Q->front);
                  Q->front = Q->rear;
              }

              Q = NULL;
              return 0;
          }
          int ClearQueue(LinkQueue *Q)
          {
              return 0;
          }
          int QueueEmpty(LinkQueue Q)
          {
              if(Q.front == Q.rear)
              {
                  return 1;
              }
              else
              {
                  return 0;
              }
          }
          int QueueLength(LinkQueue Q)
          {
              return Q.front->data;
          }
          int GetHead(LinkQueue Q,QElemType *e)
          {
              if(Q.front->next == NULL)
              {
                  perror("Queue is empty!\n");
                  *e = -1;
                  return -1;
              }
              *e = Q.front->next->data;
              return 0;
          }
          int InsertQueue(LinkQueue *Q,QElemType e)
          {
              QueuePtr p = (QueuePtr )malloc(sizeof(QNode));
              if(p == NULL)
              {
                  perror("malloc error!\n");
                  return -1;
              }

              p->data = e;
              p->next = NULL;
              (Q->rear)->next = p;
              Q->rear = p;

              Q->front->data++;
              return 0;
          }
          int DelQueue(LinkQueue *Q,QElemType *e)
          {
              if(Q->front == Q->rear)
              {
                  perror("The queue is empty!");
                  return -1;
              }

              QueuePtr p = (QueuePtr )malloc(sizeof(QNode));
              p = Q->front->next;
              *e = p->data;
              Q->front->next = p->next;
              if(Q->rear == p)
              {
                  Q->rear = Q->front;
              }
              free(p);
              Q->front->data--;
              return 0;
          }
          int PrintQueue(LinkQueue Q)
          {
              Q.front = Q.front->next;
              while(Q.front != NULL)
              {
                  printf("%d-----",Q.front->data);
                  Q.front = Q.front->next;
              }
              return 0;
          }

        109. =========================================
        110. (C版之基本操做)
        111. 1.鏈式隊列

          //隊列結點結構體

          typedef struct QNode

          { QElemType data;

            QNode *next;

          }*Queueptr;

          ------------------------------

          //指向結點的指針

          struct LinkQueue

          {  Queueptr front,rear;

          }

          [cpp]  view plain copy print ?
           
          1. <STRONG><SPAN style="COLOR: #000066; FONT-SIZE: 18px">void InitQueue(LinkQueue &Q)  
          2. // 構造一個空隊列Q   
          3.   if(!(Q.front=Q.rear=(QueuePtr)malloc(sizeof(QNode))))  
          4.     exit(OVERFLOW);  
          5.   Q.front->next=NULL;  
          6. }  
          7.   
          8. void DestroyQueue(LinkQueue &Q)  
          9. // 銷燬隊列Q(不管空否都可)   
          10.   while(Q.front)  
          11.   {  
          12.     Q.rear=Q.front->next;  
          13.     free(Q.front);  
          14.     Q.front=Q.rear;//釋放一塊內存要作兩點:1.釋放指向它的指針。2.將該指針指向空   
          15.   }  
          16. }  
          17.   
          18. void ClearQueue(LinkQueue &Q)  
          19. // 將Q清爲空隊列   
          20.   QueuePtr p,q;  
          21.   Q.rear=Q.front;  
          22.   p=Q.front->next;  
          23.   Q.front->next=NULL;//只留下頭結點   
          24.   while(p)  
          25.   {  
          26.     q=p;  
          27.     p=p->next;  
          28.     free(q);  
          29.   }  
          30. }  
          31.   
          32. Status QueueEmpty(LinkQueue Q)  
          33. // 若Q爲空隊列,則返回TRUE,不然返回FALSE   
          34.   if(Q.front->next==NULL)//注意不要把鏈式隊列的判空條件與循環隊列混淆   
          35.     return TRUE;  
          36.   else  
          37.     return FALSE;  
          38. }  
          39.   
          40. int QueueLength(LinkQueue Q)  
          41. // 求隊列的長度   
          42.   int i=0;  
          43.   QueuePtr p;  
          44.   p=Q.front;  
          45.   while(Q.rear!=p)  
          46.   {  
          47.     i++;  
          48.     p=p->next;  
          49.   }  
          50.   return i;  
          51. }  
          52.   
          53. Status GetHead(LinkQueue Q,QElemType &e)  
          54. // 若隊列不空,則用e返回Q的隊頭元素,並返回OK,不然返回ERROR   
          55.   QueuePtr p;  
          56.   if(Q.front==Q.rear)  
          57.     return ERROR;  
          58.   p=Q.front->next;  
          59.   e=p->data;  
          60.   return OK;  
          61. }  
          62.   
          63. void EnQueue(LinkQueue &Q,QElemType e)  
          64. // 插入元素e爲Q的新的隊尾元素   
          65.   QueuePtr p;  
          66.   if(!(p=(QueuePtr)malloc(sizeof(QNode)))) // 存儲分配失敗   
          67.     exit(OVERFLOW);  
          68.   p->data=e;  
          69.   p->next=NULL;  
          70.   Q.rear->next=p;  
          71.   Q.rear=p;  
          72. }  
          73.   
          74. Status DeQueue(LinkQueue &Q,QElemType &e)  
          75. // 若隊列不空,刪除Q的隊頭元素,用e返回其值,並返回OK,不然返回ERROR   
          76.   QueuePtr p;  
          77.   if(Q.front==Q.rear)  
          78.     return ERROR;  
          79.   p=Q.front->next;  
          80.   e=p->data;  
          81.   Q.front->next=p->next;  
          82.   if(Q.rear==p)  
          83.     Q.rear=Q.front;//若是隻有一個節點,那麼刪除這個節點後rear指針也就丟了,需從新賦值   
          84.   free(p);  
          85.   return OK;  
          86. }  
          87.   
          88. void QueueTraverse(LinkQueue Q,void(*vi)(QElemType))  
          89. // 從隊頭到隊尾依次對隊列Q中每一個元素調用函數vi()   
          90.   QueuePtr p;  
          91.   p=Q.front->next;  
          92.   while(p)  
          93.   {  
          94.     vi(p->data);  
          95.     p=p->next;  
          96.   }  
          97.   printf("\n");  
          98. }</SPAN></STRONG>  
          [cpp]  view plain copy print ?
           
          1. <strong><span style="font-size:18px;color:#000066;">void InitQueue(LinkQueue &Q)  
          2. // 構造一個空隊列Q  
          3.   if(!(Q.front=Q.rear=(QueuePtr)malloc(sizeof(QNode))))  
          4.     exit(OVERFLOW);  
          5.   Q.front->next=NULL;  
          6. }  
          7.   
          8. void DestroyQueue(LinkQueue &Q)  
          9. // 銷燬隊列Q(不管空否都可)  
          10.   while(Q.front)  
          11.   {  
          12.     Q.rear=Q.front->next;  
          13.     free(Q.front);  
          14.     Q.front=Q.rear;//釋放一塊內存要作兩點:1.釋放指向它的指針。2.將該指針指向空  
          15.   }  
          16. }  
          17.   
          18. void ClearQueue(LinkQueue &Q)  
          19. // 將Q清爲空隊列  
          20.   QueuePtr p,q;  
          21.   Q.rear=Q.front;  
          22.   p=Q.front->next;  
          23.   Q.front->next=NULL;//只留下頭結點  
          24.   while(p)  
          25.   {  
          26.     q=p;  
          27.     p=p->next;  
          28.     free(q);  
          29.   }  
          30. }  
          31.   
          32. Status QueueEmpty(LinkQueue Q)  
          33. // 若Q爲空隊列,則返回TRUE,不然返回FALSE  
          34.   if(Q.front->next==NULL)//注意不要把鏈式隊列的判空條件與循環隊列混淆  
          35.     return TRUE;  
          36.   else  
          37.     return FALSE;  
          38. }  
          39.   
          40. int QueueLength(LinkQueue Q)  
          41. // 求隊列的長度  
          42.   int i=0;  
          43.   QueuePtr p;  
          44.   p=Q.front;  
          45.   while(Q.rear!=p)  
          46.   {  
          47.     i++;  
          48.     p=p->next;  
          49.   }  
          50.   return i;  
          51. }  
          52.   
          53. Status GetHead(LinkQueue Q,QElemType &e)  
          54. // 若隊列不空,則用e返回Q的隊頭元素,並返回OK,不然返回ERROR  
          55.   QueuePtr p;  
          56.   if(Q.front==Q.rear)  
          57.     return ERROR;  
          58.   p=Q.front->next;  
          59.   e=p->data;  
          60.   return OK;  
          61. }  
          62.   
          63. void EnQueue(LinkQueue &Q,QElemType e)  
          64. // 插入元素e爲Q的新的隊尾元素  
          65.   QueuePtr p;  
          66.   if(!(p=(QueuePtr)malloc(sizeof(QNode)))) // 存儲分配失敗  
          67.     exit(OVERFLOW);  
          68.   p->data=e;  
          69.   p->next=NULL;  
          70.   Q.rear->next=p;  
          71.   Q.rear=p;  
          72. }  
          73.   
          74. Status DeQueue(LinkQueue &Q,QElemType &e)  
          75. // 若隊列不空,刪除Q的隊頭元素,用e返回其值,並返回OK,不然返回ERROR  
          76.   QueuePtr p;  
          77.   if(Q.front==Q.rear)  
          78.     return ERROR;  
          79.   p=Q.front->next;  
          80.   e=p->data;  
          81.   Q.front->next=p->next;  
          82.   if(Q.rear==p)  
          83.     Q.rear=Q.front;//若是隻有一個節點,那麼刪除這個節點後rear指針也就丟了,需從新賦值  
          84.   free(p);  
          85.   return OK;  
          86. }  
          87.   
          88. void QueueTraverse(LinkQueue Q,void(*vi)(QElemType))  
          89. // 從隊頭到隊尾依次對隊列Q中每一個元素調用函數vi()  
          90.   QueuePtr p;  
          91.   p=Q.front->next;  
          92.   while(p)  
          93.   {  
          94.     vi(p->data);  
          95.     p=p->next;  
          96.   }  
          97.   printf("\n");  
          98. }</span></strong>  


          2.順序隊列---循環隊列

          性質以下:

          1.頭指針指向對頭元素,尾指針指向隊尾的下一個位置。(這裏的指針都是爲指針,實際是數組序號)

          2.爲了區分隊滿與對空,則定義一個存儲空間爲MAX_QSIZE大小的隊列只容許存放MAX_QSIZE-1個數據。

          3.判空條件爲:if(Q.front ==Q.rear) return true;

             判滿條件爲:if((Q.rear+1)%MAX_QSIZE==Q.front) return true;

          4.循環隊列的長度爲:(Q.read-Q.front+MAX_SIZE)%MAX_QSIZE

          5.當刪除對頭元素或者在對尾插入元素時指針均需向後移動。操做爲:

              Q.rear=(Q.rear+1)%MAX_QSIZE;

              Q.front=(Q.front+1)%MAX_QSIZE;

          結構體定義以下:

          struct SqQueue

          {QElemType *base;//指向開闢的空間的首地址

            int front;

            int rear;

          }

          [cpp]  view plain copy print ?
           
          1. void InitQueue(SqQueue &Q)  
          2.  { // 構造一個空隊列Q   
          3.    Q.base=(QElemType *)malloc(MAX_QSIZE*sizeof(QElemType));  
          4.    if(!Q.base) // 存儲分配失敗   
          5.      exit(OVERFLOW);  
          6.    Q.front=Q.rear=0;  
          7.  }  
          8.   
          9.  void DestroyQueue(SqQueue &Q)  
          10.  { // 銷燬隊列Q,Q再也不存在   
          11.    if(Q.base)  
          12.      free(Q.base);  
          13.    Q.base=NULL;  
          14.    Q.front=Q.rear=0;  
          15.  }  
          16.   
          17.  void ClearQueue(SqQueue &Q)  
          18.  { // 將Q清爲空隊列   
          19.    Q.front=Q.rear=0;  
          20.  }  
          21.   
          22.  Status QueueEmpty(SqQueue Q)  
          23.  { // 若隊列Q爲空隊列,則返回TRUE;不然返回FALSE   
          24.    if(Q.front==Q.rear) // 隊列空的標誌   
          25.      return TRUE;  
          26.    else  
          27.      return FALSE;  
          28.  }  
          29.   
          30.  int QueueLength(SqQueue Q)  
          31.  { // 返回Q的元素個數,即隊列的長度   
          32.    return(Q.rear-Q.front+MAX_QSIZE)%MAX_QSIZE;  
          33.  }  
          34.   
          35.  Status GetHead(SqQueue Q,QElemType &e)  
          36.  { // 若隊列不空,則用e返回Q的隊頭元素,並返回OK;不然返回ERROR   
          37.    if(Q.front==Q.rear) // 隊列空   
          38.      return ERROR;  
          39.    e=Q.base[Q.front];//等價於e=*(Q.base+Q.front)   
          40.    return OK;  
          41.  }  
          42.   
          43.  Status EnQueue(SqQueue &Q,QElemType e)  
          44.  { // 插入元素e爲Q的新的隊尾元素   
          45.    if((Q.rear+1)%MAX_QSIZE==Q.front) // 隊列滿   
          46.      return ERROR;  
          47.    Q.base[Q.rear]=e;//等價於*(Q.base+Q.rear)=e   
          48.    Q.rear=(Q.rear+1)%MAX_QSIZE;  
          49.    return OK;  
          50.  }  
          51.   
          52.  Status DeQueue(SqQueue &Q,QElemType &e)  
          53.  { // 若隊列不空,則刪除Q的隊頭元素,用e返回其值,並返回OK;不然返回ERROR   
          54.    if(Q.front==Q.rear) // 隊列空   
          55.      return ERROR;  
          56.    e=Q.base[Q.front];  
          57.    Q.front=(Q.front+1)%MAX_QSIZE;  
          58.    return OK;  
          59.  }  
          60.   
          61.  void QueueTraverse(SqQueue Q,void(*vi)(QElemType))  
          62.  { // 從隊頭到隊尾依次對隊列Q中每一個元素調用函數vi()   
          63.    int i;  
          64.    i=Q.front;  
          65.    while(i!=Q.rear)  
          66.    {  
          67.      vi(Q.base[i]);  
          68.      i=(i+1)%MAX_QSIZE;  
          69.    }  
          70.    printf("\n");  
          71.  }  
            ===========================================
            (C版支循環隊列)

          #include<iostream.h>

          #include <stdlib.h>

          #include <malloc.h>

          #include<stdio.h>

          #define FALSE 0

          #define TRUE 1

          #define OK   1

          #define ERROR  0

          #define MAXSIZE 100

           

          typedef int QueueElementType;

          typedef struct

          {

              QueueElementType element[MAXSIZE];

              int front;

              int rear;

          }SeqQueue;

           

          //初始化

          int InitQueue(SeqQueue *Q)

          {

              Q->front=Q->rear=0;

              return(TRUE);

          }

           

          //入隊

          int EnterQueue(SeqQueue *Q,QueueElementType x)

          {

              if((Q->rear+1)%MAXSIZE==Q->front)

                  return(FALSE);

              Q->element[Q->rear]=x;

              Q->rear=(Q->rear+1)%MAXSIZE;

              return(TRUE);

          }

           

          //出隊

          int DeleteQueue(SeqQueue *Q,QueueElementType *x)

          {

              if(Q->front==Q->rear)

              return(FALSE);

              *x=Q->element[Q->front];

              Q->front=(Q->front+1)%MAXSIZE;

              return(TRUE);

          }

           

          //求長度

           

          int LengthQueue(SeqQueue *Q)

          {

             printf("%d",(Q->rear-Q->front+MAXSIZE) % MAXSIZE);

             printf("\n");

             return(TRUE);

          }

           

           

           

          //輸出鏈表

           

          void PrintfQueue(SeqQueue *Q)

          {

              int j;

            if(Q->front==Q->rear)

                cout<<"隊列爲空"<<endl;

              else

              {

                  j=((Q->rear-Q->front+MAXSIZE) % MAXSIZE)-1;

                  for(int i=0; i<=j; i++)

                  printf("%d",Q->element[(Q->front+i)%MAXSIZE]);

                  printf("\n");

              }

          }

           

           

          //判斷循環隊列是否爲空或爲滿

          void JudgeQueue(SeqQueue *Q)

          {

              if(Q->front==Q->rear)

              {

                  printf("該隊列爲空");

                  printf("\n");

              }

              else if((Q->rear+1)%MAXSIZE==Q->front)

              {

                  printf("該隊列爲滿");

                  printf("\n");

              }

              else

              {

                  printf("該隊列既不爲空也不爲滿");

                  printf("\n");

              }

          }

           

          //銷燬隊列

          void DestroyQueue(SeqQueue *Q)

          {

             Q->front=Q->rear=0;

          }

           

           

          void main()

          {

                 SeqQueue Q;

                 InitQueue(&Q);

          int flag=1;

                 printf("        ************^^^^^^^循環隊列功能菜單^^^^^^^************");

                 printf("\n");

           printf("請選擇操做:");

                  printf("\n");

                  printf("1.入隊操做");

                  printf("\n");

                  printf("2.出隊操做");

                  printf("\n");

                  printf("3.判斷隊列空或滿");

                  printf("\n");

                  printf("4. 求隊列長度");

                  printf("\n");

                  printf("5.銷燬隊列");

                  printf("\n");

                  printf("6.退出");

                  printf("\n");

                   

           while(flag)

               {

                 int x,e;

                

              cin>>e;

           

             switch(e){

          case 1:printf("請輸入要入隊的整型值:(限一個)");

                 printf("\n");

                    cin>>x;

                    EnterQueue(&Q,x);

                    printf("隊列爲:");

                      PrintfQueue(&Q);

                    break;

             case 2: DeleteQueue(&Q,&x);

                     printf("隊列爲:");

                     PrintfQueue(&Q);

                     break;

             case 3:JudgeQueue(&Q);

                     break;

             case 4:printf("鏈表長度爲:");

                     LengthQueue(&Q) ;

                     break;

             case 5:DestroyQueue(&Q);

                    printf("銷燬成功!");

                     break;

             case 6:flag=0;

                     break;

           }

          }

          循環隊列基本操做程序 - 匿名的寶貝 - STEP BY STEP

           

           

           

           

          (C版之雙端隊列)

          用數組實現棧,循環隊列,雙端隊列的方法其實很是簡單。

          其優點在於:
          能達到棧與隊列的通常用途,且實現簡易,對於通常的不太大的棧,使用數組就能夠達到要求了,只需定義一兩個宏就能很好的進行操做。還有比較好的隨機訪問的功能。
          不足在於:須要佔用一部分靜態空間,尤爲是棧或者隊列很大或者節點結構很大的時候,就不如鏈棧那麼節省空間了,功能也不夠強大,如過空間不夠,很容易就會出現滿棧或者滿隊列。
           
          這是他們的實現代碼:
           
          值得注意的是,一般不須要定義這麼多函數,只需定義push,pop,inqueue,dequeue,linquuee,ldequeue,
          rinqueue,rdequeue這些須要的宏的就好了,須要什麼定義什麼。對於較大的棧與隊列,建議使用鏈棧(隊列)。
           
          #include<stdio.h>
           
           
          #define STACKSIZE  100
           
           
          typedef struct _ELE
          {
          int num;
          }Node;
           
          Node Stack[STACKSIZE];
          int top = -1;
           
          void stack_full()
          {
          fprintf( stderr, "Stack full.\n" );
          return;
          }
           
          void stack_empty()
          {
          fprintf( stderr, "Stack empty.\n" );
          return;
          }
           
          void push( int * top, Node item )
          {
          if( *top == STACKSIZE )
          {
          stack_full();
          return;
          }
           
          *top = *top + 1;
          Stack[*top] = item;
           
          }
           
          Node * pop( int * top )
          {
          if( *top == -1 )
          {
          stack_empty();
          return ( NULL );
          }
          int temp = * top;
          *top = *top - 1;
          return ( &Stack[temp] );
          }
           
          int isempty( int * top )
          {
          return ( *top == -1 );
          }
           
          int isfull( int * top )
          {
          return ( *top == STACKSIZE );
          }
          int main()
          {
          Node n;
          n.num = 3;
          push( &top, n );
          n.num = 4;
          push( &top, n );
          n.num = 5;
          push( &top, n  );
          n.num = 6;
          push( &top, n  );
           
          pop( &top );
           
          return ( 0 );
          }
           
           
          //循環隊列
           
          #include <stdio.h>
           
          #define QUEUESIZE  4
           
          int Queue[QUEUESIZE];
           
          int front = 0;
          int rear = 0;
           
          int isempty()
          {
          return ( front == rear );
          }
           
          void queue_empty()
          {
          fprintf( stderr, "queue empty.\n" );
          }
           
          int isfull()
          {
          return ( rear == front - 1 );
          }
           
          void queue_full()
          {
          fprintf( stderr, "queue full.\n" );
          }
           
          void inqueue( int * rear, int front, int item )
          {
          if( (*rear + 1)%QUEUESIZE == front )
          {
          queue_full();
          return;
          }
           
          Queue[*rear] = item;
          *rear = ( *(rear) + 1 )%QUEUESIZE;
          return;
          }
           
          int dequeue( int rear, int * front )
          {
          int temp = 0;
          if( rear == *front )
          {
          queue_empty();
          return ( -1 );
          }
          temp = Queue[*front];
          *front = (*front + 1)%QUEUESIZE;
          return temp;
          }
           
          int main()
          {
          inqueue( &rear, front, 2 );
          inqueue( &rear, front, 3 );
          inqueue( &rear, front, 4 );
          inqueue( &rear, front, 5 );
          while( !isempty() )
          {
          printf( "%d\n", dequeue( rear, &front ) );
          }
          inqueue( &rear, front, 6 );
          inqueue( &rear, front, 1 );
          inqueue( &rear, front, 1 );
          while( !isempty() )
          {
          printf( "%d\n", dequeue( rear, &front ) );
          }
           
          while( !isempty() )
          {
          printf( "%d\n", dequeue( rear, &front ) );
          }
          return ( 0 );
          }
           
           
           
          //雙端隊列
           
          #include <stdio.h>
           
          #define MAX  100
           
          int queue[MAX];
          int l = 0;
          int r = 0;
           
          int isempty()
          {
          return ( l == r );
          }
           
          int linqueue( int item )
          {
          if( l == 0 )
          {
          fprintf( stderr, "no ispace in left.\n" );
          return -1;
          }
           
          else
          {
          queue[l --] = item;
          return ( l );
          }
          }
           
          int rinqueue( int item )
          {
          if( r == MAX)
          {
          fprintf( stderr, "no ispace in right.\n" );
          return -1;
          }
           
          else
          {
          queue[r ++] = item;
          return ( r );
          }
          }
           
          int ldequeue()
          {
          if( l >= r )
          {
          fprintf( stderr, "queue empty.\n" );
          return ( -1 );
          }
          return( queue[l++] );
          }
          int rdequeue()
          {
          if( l >= r )
          {
          fprintf( stderr, "queue empty.\n" );
          return ( -1 );
          }
          return ( queue[r--] );
          }
           
          int main()
          {
          rinqueue( 4 );
          rinqueue( 5 );
          rinqueue( 6 );
          rinqueue( 7 );
          printf( "%d\n",ldequeue() );

           

           

           

           

           

          deque雙端隊列容器

          1、基本原理

              deque的元素數據採用分塊的線性結構進行存儲,如圖所示。deque分紅若干線性存儲塊,稱爲deque塊。塊的大小通常爲512個字節,元素的數據類型所佔用的字節數,決定了每一個deque塊可容納的元素個數。

          全部的deque塊使用一個Map塊進行管理,每一個Map數據項記錄各個deque塊的首地址Mapdeque的中心部件,將先於deque塊,依照deque元素的個數計算出deque塊數,做爲Map塊的數據項數,建立出Map塊。之後,每建立一個deque塊,都將deque塊的首地址存入Map的相應數據項中。

          Mapdeque塊的結構之下,deque使用了兩個迭代器M_startM_finish,對首個deque塊和末deque塊進行控制訪問。迭代器iterator共有4個變量域,包括M_firstM_lastM_curM_nodeM_node存放當前deque塊的Map數據項地址,M_firstM_last分別存放該deque塊的首尾元素的地

          址(M_last實際存放的是deque塊的末尾字節的地址),M_cur則存放當前訪問的deque雙端隊列的元素地址。

          50、Deque雙端隊列容器 - EdwardLewis - 墨涵天地50、Deque雙端隊列容器 - EdwardLewis - 墨涵天地

          2、應用

          1、建立

          1deque() 

          建立一個沒有任何元素的deque對象。此構造函數的更通常形式是「deque(const A& a = A())」,A是一個內存分配器,可缺省。如deque<int> d;

          2deque(size_type n) 

          建立一個具備n個元素的deque對象,每一個元素採用它的類型下的默認值。deque<int> d(10); //默認值爲0

          3deque(size_type n, const T& value) 

          建立一個具備n個元素的deque對象,這些元素的初始值爲value

          4deque(const deque&) 

          deque的拷貝構造函數,經過拷貝一個deque對象的元素值,建立一個新的deque對象。此時,新舊deque對象具備相同塊數的deque塊,各自內部的元素也對應相等。

          deque<char> d1(5,'k';

          deque<char> d2(d1); 

          5deque(const InputIterator first, const InputIterator last, const A& a=A()) 

          將迭代器區間[first,last)所指的元素拷貝到一個新建立的deque對象中,其中內存分配器可缺省。 

          //利用int數組iArray,建立了一個deque對象

          int iArray [] = {11, 13, 19, 23, 27}; 

          deque<int> d(iArray, iArray + 5); 

          2、初始化

          利用deque提供的push_back()函數,可在尾部壓入新元素value,經常使用做deque容器的初始化賦值。

          3、訪問

          deque的元素一樣可採用數組和迭代器方式進行訪問,用「d[i]」取得deque對象d的第i個元素(0id.size()),或用迭代器i的「*」操做「*i」取得i所指向的元素。

          1iterator begin()

          2iterator end() 

          可反向遍歷deque雙端隊列中元素迭代器: 

          1reverse_iterator rbegin() 

          2reverse_iterator rend()   

          4、插入

          1deque 具備高效的頭部插入元素的函數push_front()。 

          void push_front(const T&) 

          2將在pos位置以前,插入新元素x。 

          iterator insert(iterator pos, const T& x) 

          5、刪除

          1void pop_front() 

          刪除deque的第一個元素。 

          2void pop_back() 

          刪除deque的最後一個元素。 

          3iterator erase(iterator pos) 

          刪除pos所指向的元素。 

          4iterator erase(iterator first, iterator last)

          刪除迭代器區間[first,last)所指向的全部元素。 

          5void clear() 

          刪除全部元素。 

          6、交換

          void swap(deque&) 

          d1.swap(d2);

          7、其它

          1bool empty() 

          判斷deque容器是否已有元素,是則返回true,不然返回false。 

          2size_type size() 

          當前deque容器的元素個數。 

          3size_type max_size() 

          系統所支持的deque容器的最大元素個數。 

          4reference front() 

          deque容器的首元素(引用返回),要求deque不爲空。 

          5reference back() 

          deque容器的末元素(引用返回),要求deque不爲空。

           

           

           

           

          (C++版雙端隊列)

           

          1. /* 
          2.  * 用數組實現一個兩端都能插入和刪除操做的雙端隊列 
          3.  */  
          4.   
          5. static const int nLength = 5;  
          6. static int deque[nLength];  
          7. static int nIdxHead = 0;  
          8. static int nIdxTail = 0;  
          9.   
          10. enum Err  
          11. {  
          12.     NoErr,  
          13.     errOverFlow,  
          14.     errUnderFlow,  
          15. };  
          16.   
          17. // 頭進隊  
          18. Err EnDequeHead(int x)  
          19. {  
          20.     if (((nIdxHead + nLength - 1) % nLength) == nIdxTail)  
          21.         return errOverFlow;  
          22.     nIdxHead = ((nIdxHead + nLength - 1) % nLength);  
          23.     deque[nIdxHead] = x;  
          24.     return NoErr;  
          25. }  
          26.   
          27. // 頭出隊  
          28. Err DeDequeHead(int *pX)  
          29. {  
          30.     if (nIdxHead == nIdxTail)  
          31.         return errUnderFlow;  
          32.     if (NULL != pX)  
          33.         *pX = deque[nIdxHead];  
          34.     nIdxHead = (nIdxHead + 1) % nLength;  
          35.     return NoErr;  
          36. }  
          37.   
          38. // 尾進隊  
          39. Err EnDequeTail(int x)  
          40. {  
          41.     if (((nIdxTail + 1) % nLength) == nIdxHead)  
          42.         return errOverFlow;  
          43.     deque[nIdxTail] = x;  
          44.     nIdxTail = ((nIdxTail + 1) % nLength);  
          45.     return NoErr;  
          46. }  
          47.   
          48. // 尾出隊  
          49. Err DeDequeTail(int *pX)  
          50. {  
          51.     if (nIdxHead == nIdxTail)  
          52.         return errUnderFlow;  
          53.     nIdxTail = (nIdxTail + nLength - 1) % nLength;  
          54.     if (NULL != pX)  
          55.         *pX = deque[nIdxTail];  
          56.     return NoErr;  
          57. }  

           

           

           

          (python版之雙端隊列)

          什麼是雙端隊列

          deque,全名double-ended queue)是一種具備隊列和棧的性質的數據結構。雙端隊列中的元素能夠從兩端彈出,其限定插入和刪除操做在表的兩端進行。

          下面簡單的介紹一下python中雙端隊列的操做函數;

          from collections import deque   #首先從collections 模塊中導入deque類

          下來咱們定義一個雙端隊列

          1.A=deque([])  #建立一個空的雙隊列
          2.A.append(n)  #從右邊像隊列中增長元素 ,n表示增長的元素
          3.A.appendleft(n) #從左邊像隊列中增長元素,n表示增長的元素
          4.A.clear()       #清空隊列
          5.A.count(n)      #在隊列中統計元素的個數,n表示統計的元素
          6.A.extend(n)      #從右邊擴展隊列,n表示擴展的隊列
          7.A.extendleft(n)  #從左邊擴展隊列,n表示擴展的隊列
          8.A.pop()         #從隊列的右邊刪除元素,而且返回刪除值
          9.A.popleft()     #從隊列的左邊刪除元素,而且返回刪除值
          10.A.remove(n)      #從隊列中刪除指定的值
          11.A.reverse()     #翻轉隊列
          12.A.rotate(n)      #旋轉隊列,默認時值爲1,由右邊開始旋轉,負值表明左邊旋轉,n表明從隊列的第一個元素開始,n從1開始計數

          雙端隊列旋轉演示圖

          python <wbr>雙端隊列

           

           

           

           

          (C++之兩個普通隊列和一個優先權隊列)

          #ifndef QUEUE_H_

          #define QUEUE_H_

           

          #include "Chain.h"

           

          #include <cassert>

          #include <cstddef>

          #include <stdexcept>

           

          //固定事務數的隊列

          //用數組實現

          template <class Type>

          class FixQueue {

          public:

             FixQueue( size_t sz );

             virtual ~FixQueue();

            

             bool EnQueue( const Type& item);

             Type DeQueue();

             Type GetFront();

             void MakeEmpty() { m_ifront = m_irear = 0; }

             bool IsEmpty() const { return  m_ifront == m_irear; }

             bool IsFull() const { return (m_irear+1)%m_uiMaxSize == m_ifront; }

             size_t Length() const { return (m_irear+m_uiMaxSize-m_ifront)%m_uiMaxSize; }

          private:

             int m_irear, m_ifront;

             Type* m_pElement;

             size_t m_uiMaxSize;

          };

           

          //--------------------------------------

          //FixQueue template implementation

          //

          template <class Type>

          FixQueue<Type>::FixQueue( size_t sz = 15) : m_uiMaxSize(sz)

          {

             m_pElement = new Type[m_uiMaxSize];

             assert( m_pElement != 0);   //其實這樣作沒有做用

             m_ifront = m_irear = 0; 

          }

           

          template <class Type>

          FixQueue<Type>::~FixQueue()

          {

             delete []m_pElement;

          }

           

          template <class Type>

          bool FixQueue<Type>::EnQueue( const Type& item )

          {

             //隊列不滿則加入元素

             if(IsFull()) return false;

             m_irear = (m_irear+1) % m_uiMaxSize; //計算隊尾值

             m_pElement[m_irear] = item;

             return true;

          }

           

          template <class Type>

          Type FixQueue<Type>::DeQueue()

          {

             if(IsEmpty())

             {

                MakeEmpty();

                throw std::out_of_range("Out Of bounds of Queue!/n");

             }

             else

             {

                m_ifront = (m_ifront+1) % m_uiMaxSize;

                return m_pElement[m_ifront];  

             }

          }

           

          template <class Type>

          Type FixQueue<Type>::GetFront()

          {

             //返回隊列頭元素的值

             if(IsEmpty())

             {

                MakeEmpty();

                throw std::out_of_range("Out Of bounds of Queue!/n");

             }

             else

             {

                return m_pElement[(m_ifront+1) % m_uiMaxSize];

             } 

          }

           

          //FixQueue Over!

           

          //ChainQueue

          //鏈式隊列,雖然鏈式隊列從抽象意義上來講"is a Chain"

          //可是仔細分析,很容易發現鏈式隊列只不過是可以在"鏈頭刪除元素","鏈尾添加元素"的普通鏈表

          //更好的表示是: 鏈式隊列"has a general Chain for specific use"

          template <class Type>

          class ChainQueue {

          public:

             ChainQueue();

             virtual ~ChainQueue();

            

             virtual void EnQueue( const Type& item);

             virtual Type DeQueue();

             Type GetFront();

             void MakeEmpty();

             bool IsEmpty() const;

             size_t Length() const ;

           

          private:

             Chain<Type> chain;

          };

           

           

          template <class Type>

          ChainQueue<Type>::ChainQueue() {}

           

          template <class Type>

          ChainQueue<Type>::~ChainQueue() {}

          template <class Type>

          void ChainQueue<Type>::EnQueue( const Type& item)

          {

             //新加元素

             try

             {

                chain.Appen(item);

             }

             catch (...)

             { throw; }

          }

           

          template <class Type>

          Type ChainQueue<Type>::DeQueue()

          {

             Type tmp;

             try

             {

                chain.Delete(1,tmp);

             }

             catch(...)

             {

                throw;

             }

             return tmp;

          }

           

          template <class Type>

          Type ChainQueue<Type>::GetFront()

          {

             Type tmp;

             if(!chain.Find(1,tmp)) throw std::out_of_range("Out Of bounds of Queue!/n");

             return tmp;

          }

           

          template <class Type>

          void ChainQueue<Type>::MakeEmpty()

          {

             chain.Erase();

          }

           

          template <class Type>

          bool ChainQueue<Type>::IsEmpty() const

          {

             return (chain.Length() == 0);

          }

           

          template <class Type>

          size_t ChainQueue<Type>::Length() const

          {

             return (size_t)chain.Length();

          }

           

           

          //============================================================

          //PRQueue 實現一個按優先權重操做的隊列

          //顯然,無需從新實現完整的優先權隊列

          //優先權隊列只不過是一個特殊的隊列罷了,優先級隊列插入元素方式不一樣,

          //要overwrite EnQueue();

          //這裏採用繼承鏈式隊列(考慮到元素插入的效率因素,鏈表划算)

          //一個更好的方法是利用交叉鏈表實現優先級隊列,優先級別爲行列表,同優先級的任務放到列鏈表中,這裏只是從新實現按權重插入元素

          //=============================================================

          //定義一個帶優先權的結構

          template <class Type>

          typedef struct PRItem

          {

             int priority;   //優先權

             Type item;      //元

            

             //只須要重載一個 <=就好了,這樣恰好可以實現

             //1:先按照優先級處理

             //2:同優先級的FIFO方式處理

             bool operator<=( const PRItem& item) {

                return priority <= item.priority;

             }

          };

           

           

          template <class Type>

          class PRQueue : public ChainQueue< PRItem<Type> > //鬱悶,模板中模板類型

          {

            

          public:

             PRQueue();

             ~PRQueue();

             void EnQueue( const PRItem<Type>& item)        //overwrite

             {

                typedef PRItem<Type> PRITEM;

           

                typename Chain<PRITEM>::iterator iter = Chain<PRITEM>::chain.begin();

                int x=1;

                //按優先權插入尋找插入位置

                while(iter != Chain<PRITEM>::chain.end() && iter.current() <= item)

                {

                   x++;

                   iter++;

                }

               

                Chain<PRITEM>::chain.Insert(x, item);

             }

            

             void EnQueue( const Type& item, int priority)     //overload

             {

                PRItem<Type> tmp;

                tmp.item = item;

                tmp.priority = priority;

                EnQueue(tmp);     

             }

            

          };

           

           

          #endif /*QUEUE_H_*/

相關文章
相關標籤/搜索