循環隊列的實現

主要代碼:

/****************************************************
  @Title: 數據結構實驗
  @Name: <實驗3-4> <循環隊列> 
  @Object:
      [實驗目的] 實現循環隊列的基本操作,並進行測試。

      [實驗提示]
        1. 在文件 sqqueue.h 中完成 SqQueue 的類型定義

        2. 實現 SqQueue 的基本操作
           注意:取隊頭元素、入隊列和出隊列的前提

  @Files:
      dsp0304.cpp [*]
         測試循環隊列的主程序 
      sqqueue.h [*]
         循環隊列的實現 
  @Usage:
      請查看"TO-DO列表",根據要求完成代碼
  @Copyright: BTC 2004, Zhuang Bo
  @Author: Zhuang Bo
  @Date: 2004
  @Description:
*****************************************************/

#include <stdio.h>
#include <stdlib.h>
#include "sqqueue.h"

//初始化系統 
void Initialize(SqQueue &q); 
//顯示操作菜單
void ShowMenu();
//讀取用戶命令
int GetCommand();  
//執行用戶命令 
int DoCommand(int cmd, SqQueue &q);  
//結束執行
void Finalize(SqQueue &q);   

////////////////////////////////////////////
//主程序 
int main()
{
    SqQueue q; //循環隊列 
    int cmd; //用戶命令 

    //系統初始化
    Initialize(q);
    //顯示操作菜單 
    ShowMenu();
    //進入主循環    
    while(1) {
        //讀取用戶命令(0 表示退出) 
        cmd = GetCommand();
        //執行命令cmd操作隊列q
        DoCommand(cmd,q);
        //退出命令 
        if( cmd == 0 ) break;  // 退出
    }
    /* NOTE: 以上主循環還可以簡化成 
     * while(DoCommand(GetCommand(),q));
     */

    //結束前執行的操作 
    Finalize(q);

    system("pause"); //暫停 
}

////////////////////////////////////////////
//函數的定義 

//初始化系統 
void Initialize(SqQueue &q)
{
    InitQueue(q); //初始化隊列 
}

//顯示操作菜單
void ShowMenu()
{
    printf("1)EnQueue 2)DeQueue 3)Clear 4)Empty"
           " 5)Length 6)Head 7)View 9)Menu 0)Quit\n");
}

//讀取用戶命令
int GetCommand()
{
    int cmd=-1;
    printf(">");
    if(scanf("%d", &cmd)<1)
        fflush(stdin); //處理輸入錯誤 
    return cmd;
}

//結束執行
void Finalize(SqQueue &q)
{
    DestroyQueue(q); //銷燬隊列 
    printf("程序已經結束\n"); 
}  

//執行用戶命令cmd, 測試隊列的各種操作 
//    執行結束後返回命令(便於書寫主循環)
int DoCommand(int cmd, SqQueue &q)
{
    int e;

    switch(cmd) {
    case 1: //EnQueue......................
        printf("輸入入隊列的數據:"); 
        if(scanf("%d",&e)<1) {
            printf("輸入錯誤\n"); 
            fflush(stdin);
        } else if(EnQueue(q,e)==OK)
            printf("入隊列成功\n" );
        else
            printf("入隊列失敗\n");
        break; 
    case 2: //DeQueue......................
        if( DeQueue(q,e)==OK )
            printf("%d 出隊列\n", e);
        else
            printf("出隊列失敗\n"); 
        break;
    case 3: //Clear........................
        if(ClearQueue(q)==OK)
            printf("隊列已清空\n");
        else
            printf("清空隊列失敗\n");        
        break;
    case 4: //Empty........................
        if(QueueEmpty(q)==TRUE)
            printf("隊列空\n" );
        else
            printf("隊列不空\n"); 
        break;
    case 5: //Length.......................
        printf("隊列長度: %d\n", QueueLength(q)); 
        break;
    case 6: //Head.........................
        if(GetHead(q,e)==OK)
            printf("隊頭元素: %d\n", e);
        else
            printf("取隊頭元素失敗\n"); 
        break;
    case 7: //View.........................
        /* TODO (#9#): 實現SqQueue類型後使用QueueView()函數 */
        QueueView(q);
        break;
    case 9: //Menu.........................
        ShowMenu();
    case 0: //Quit.........................
        //後面 return cmd; 返回0可以結束主循環 
        break;
    default:
       printf("命令錯誤\n"); 
    }

    return cmd; //返回最近執行的命令 
}


/*
  Name: 循環隊列 
  Copyright: BTC 2004
  Author: Zhuang Bo
  Date: 2004
  Description:
     [Include] 
        ds.h
     [Constants]
        MAXQSIZE
     [Types]
        ElemType
        SqQueue
     [Functions]
        InitQueue(&Q)
        DestroyQueue(&Q)
        ClearQueue(&Q)
        QueueEmpty(Q)
        QueueLength(Q)
        GetHead(Q,&e)
        EnQueue(&Q,e)
        DeQueue(&Q,&e)
     [For Debug]
        PrintElem(ElemType e)
        QueueView(Q)
*/

#ifndef SQQUEUE_H_INCLUDED
#define SQQUEUE_H_INCLUDED /* 防止重複包含 */

//////////////////////////////////////////
//包含頭文件 
#include <stdlib.h>
#include "ds.h" // OK, Status 等定義 

//數據元素的類型(缺省使用int型)
#ifndef ElemType
#define ElemType int
#define USE_DEFAULT_ELEMTYPE /* 使用缺省類型的標誌 */
#endif //ElemType

//////////////////////////////////////////
//循環隊列的存儲結構

#define MAXQSIZE 64 /* 循環隊列的最大容量 */
typedef struct {
    /* TODO (#1#): 這裏完成循環隊列的類型定義 */
    ElemType *base;
    int front;
    int rear;
    //....................................
} SqQueue;


//////////////////////////////////////////
//循環隊列的基本操作 

//構造一個空隊列Q
Status InitQueue(SqQueue &Q)
{
    /* TODO (#2#): 構造空隊列 */
    Q.base=(ElemType*)malloc(MAXQSIZE*sizeof(ElemType));
    if(!Q.base){
        exit(0);
    }
    Q.front=Q.rear=0;
    return OK; //TODO: 替換這行代碼,以下同
    //....................................
}

//銷燬隊列Q 
//  前提:隊列Q已存在 
Status DestroyQueue(SqQueue &Q)
{
    /* TODO (#3#): 銷燬隊列 */
    if(Q.base){
        free(Q.base);
        return OK;
    }
    else
        return ERROR;

    //....................................
}

//將隊列Q清爲空隊列
//  前提:隊列Q已存在
Status ClearQueue(SqQueue &Q)
{
    /* TODO (#4#): 清空隊列 */
    if(Q.base){
        Q.front=Q.rear;
        return  OK;
    }
    else
        return ERROR;
    //....................................
}

//若隊列Q爲空,則返回TRUE,否則FALSE 
//  前提:隊列Q已存在
Status QueueEmpty(SqQueue Q)
{
    /* TODO (#5#): 判斷隊列是否爲空 */
    if(Q.rear==Q.front){
        return TRUE; 
    }
    return FALSE;
    //....................................
}

//返回隊列Q的元素個數,即隊列長度
//  前提:隊列Q已存在 
int QueueLength(SqQueue Q)
{
    /* TODO (#6#): 返回隊列長度 */

    return (Q.rear-Q.front+MAXQSIZE)%MAXQSIZE;
    //....................................
}

//取隊列Q頭元素用e返回
//  前提:隊列Q存在且非空
Status GetHead(SqQueue Q, ElemType &e)
{
    /* TODO (#7#): 取隊頭元素存入e */
    if(Q.front==Q.rear){//隊列爲空
        return ERROR;      
    }
    e=Q.base[Q.front];
    return OK;//返回操作狀態(成功:OK,失敗:ERROR)
    //....................................
}

//插入元素e作爲隊列Q的新的隊尾元素
//  前提:隊列Q存在且未滿
Status EnQueue(SqQueue &Q, ElemType e)
{
    /* TODO (#8#): 元素e入隊列 */
    if((Q.rear+1)%MAXQSIZE==Q.front){
        return ERROR;
    }
    Q.base[Q.rear]=e;
    Q.rear=(Q.rear+1)%MAXQSIZE;
    return OK;//返回操作狀態(成功:OK,失敗:ERROR)
    //....................................
}

//刪除隊列Q的隊頭元素,並用e返回 
//  前提:隊列Q存在且非空 
Status DeQueue(SqQueue &Q, ElemType &e)
{
    /* TODO (#9#): 出隊列存入e */
    if(Q.front==Q.rear){
        return ERROR;
    }
    e=Q.base[Q.front];
    Q.front=(Q.front+1)%MAXQSIZE;
    return OK ;//返回操作狀態(成功:OK,失敗:ERROR)
    //....................................
}

//////////////////////////////////////////

//TODO: 定義好 SqQueue 類型後使用 QueueView 函數 

#include <stdio.h>
//查看隊列狀態(調試用)
void QueueView(SqQueue Q)
{
   //extern void PrintElem(ElemType e);//打印數據用 
   int i=0;
   if(Q.front<0||Q.front>=MAXQSIZE||Q.rear<0||Q.rear>=MAXQSIZE){
       printf("隊列未初始化\n"); 
       return ;
   }
   printf("---Queue View---\n");
   printf("front=%d , rear=%d\n", Q.front, Q.rear);
   if(Q.rear>=Q.front) {
       printf(".....   ......\n");
       for(i=Q.front; i<Q.rear; i++) {
           printf("%5d\t", i);
           printf("%d",Q.base[i]);
           printf("\n");
       }
       if(i<MAXQSIZE) printf(".....   ......\n");
   } else {       
       for(i=0; i<Q.rear; i++) {
           printf("%5d\t", i);
           printf("%d",Q.base[i]);
           printf("\n");
       }
       printf(".....   ......\n");
       for(i=Q.front; i<MAXQSIZE; i++) {
           printf("%5d\t", i);
           printf("%d",Q.base[i]);
           printf("\n");
       }
   }
   printf("--- view end ---\n");
}


//取消ElemType的默認定義,以免影響其它部分 
#ifdef USE_DEFAULT_ELEMTYPE
#undef ElemType
#undef USE_EFAULT_ELEMTYPE
#endif

#endif //SQQUEUE_H_INCLUDED

運行結果:

這裏寫圖片描述
這裏寫圖片描述

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章