1. 程式人生 > >c語言實現佇列舉例

c語言實現佇列舉例

標頭檔案

/*
 * my_queue.h
 *
 *  Created on: Dec 3, 2018
 *      Author: lgh
 */

#ifndef INCLUDE_MY_QUEUE_H_
#define INCLUDE_MY_QUEUE_H_

#include <stdio.h>
#include <malloc.h>

/* 佇列: 只允許在表的一端(隊尾rear)進行插入操作,而在另一端(隊頭front)進行刪除操作的線性表
 * 插入操作簡稱為入隊  刪除操作簡稱為出隊   佇列具有先進先出的特點
 */

/*=====佇列的入隊、出隊示意圖========
 *
 *  出隊 ----------------- 入隊
 *   <--- a1,a2,a3,...,an <---
 *      -----------------
 *
 *================================
*/ typedef enum { OK=0, //正確 ERROR=1, //出錯 TRUE=2, //為真 FALSE=3 //為假 }status; typedef int ElemType; //巨集定義佇列的資料型別 #define MAX_SIZE 20 /*一、使用陣列儲存佇列的稱為靜態順序佇列 *二、使用動態分配的指標的稱為動態順序佇列*/ // 【這裡的是動態順序佇列】 typedef struct { ElemType *pBase; //陣列指標 ElemType front; //隊頭索引 ElemType rear; //
隊尾索引 int maxSize; //當前分配的最大容量 }queue; //建立空佇列 queueCapacity-佇列容量 status initQueue(queue *PQueue,int queueCapacity); //銷燬佇列 void destroyQueue(queue *PQueue); //清空佇列 void clearQueue(queue *PQueue); //判斷佇列是否為空 status isEmpityQueue(queue *PQueue); //判斷佇列是否為滿 status isFullQueue(queue *PQueue); //獲得佇列長度 int
getQueueLen(queue *PQueue); //新元素入隊 [先進先出原則:在隊尾的位置插入] element-要插入元素 status enQueue(queue *PQueue,ElemType element); //新元素出隊,同時儲存出隊的元素 [先進先出原則:在隊頭的位置刪除] status deQueue(queue *PQueue,ElemType *pElement); //遍歷佇列 void queueTraverse(queue *PQueue); #endif /* INCLUDE_MY_QUEUE_H_ */

 

原始檔

/*
 * my_queue.c
 *
 *  Created on: Dec 3, 2018
 *      Author: lgh
 */

#include "my_queue.h"

/* 佇列: 只允許在表的一端(隊尾rear)進行插入操作,而在另一端(隊頭front)進行刪除操作的線性表
 * 插入操作簡稱為入隊  刪除操作簡稱為出隊   佇列具有先進先出的特點
 */

/*=====佇列的入隊、出隊示意圖========
 *
 *  出隊 ----------------- 入隊
 *   <--- a1,a2,a3,...,an <---
 *      -----------------
 *
 *================================*/

//建立佇列 queueCapacity-佇列容量
status initQueue(queue *PQueue,int queueCapacity)
{
    //給陣列指標分配記憶體
    PQueue->pBase = (ElemType *)malloc(sizeof(ElemType)*queueCapacity);
    if(!PQueue->pBase)
    {
        printf("給陣列指標分配記憶體失敗\n");
        return ERROR;
    }

    PQueue->front = 0; //最開始建立時,隊頭索引為0
    PQueue->rear = 0;  //最開始建立時,隊尾索引為0
    PQueue->maxSize = queueCapacity;

    return OK;
}

//銷燬佇列
void destroyQueue(queue *PQueue)
{
    free(PQueue);  //釋放佇列陣列指標指向的記憶體
    PQueue = NULL; //佇列陣列指標重新指向NULL,避免成為野指標
}

//清空佇列
void clearQueue(queue *PQueue)
{
    PQueue->front = 0; //隊頭索引清0
    PQueue->rear = 0;  //隊尾索引清0
}

//判斷佇列是否為空
status isEmpityQueue(queue *PQueue)
{
    if( PQueue->front == PQueue->rear )  //隊頭==隊尾,說明為空
        return TRUE;

    return FALSE;
}

/*
 *在迴圈佇列中,“隊滿”和“隊空”的條件有可能是相同的,都是front==rear,
 *這種情況下,無法區別是“隊滿”還是“隊空”。
 *針對這個問題,有3種可能的處理方法:
 *(1)另設一個標誌以區別是“隊滿”還是“隊空”。(即入隊/出隊前檢查是否“隊滿”/“隊空”)
 *(2)設一個計數器,此時甚至還可以省去一個指標。
 *(3)少用一個元素空間,即約定隊頭指標在隊尾指標的下一位置時就作為“隊滿”的標誌,
 *即“隊滿”條件為:(PQueue->rear+1)%MAX_SIZE == PQueue->front。
 *  【這裡採用了第3種處理方法】
 */
//判斷佇列是否為滿
status isFullQueue(queue *PQueue)
{
    if( (PQueue->rear+1)%PQueue->maxSize == PQueue->front )  //佇列滿
        return TRUE;

    return FALSE;
}

//獲得佇列長度
int getQueueLen(queue *PQueue)
{
    //正常情況下,佇列長度為隊尾隊頭指標之差,但如果首尾指標跨容量最大值時,要%
    return (PQueue->rear - PQueue->front + PQueue->maxSize)%PQueue->maxSize;
}

//新元素入隊 [先進先出原則:在隊尾的位置插入] element-要插入元素
status enQueue(queue *PQueue, ElemType element)
{
    if(isFullQueue(PQueue)==TRUE)
    {
        printf("佇列已滿,不能再插入元素了!\n");
        return FALSE;
    }

    //向佇列中新增新元素
    PQueue->pBase[PQueue->rear] = element;
    PQueue->rear = (PQueue->rear+1) % PQueue->maxSize; //將rear賦予新的合適的值

    return TRUE;
}

//新元素出隊,同時儲存出隊的元素 [先進先出原則:在隊頭的位置刪除]
status deQueue(queue *PQueue,ElemType *pElement)
{
    //如果佇列為空,則返回false
    if(isEmpityQueue(PQueue)==TRUE)
    {
        printf("佇列為空,出隊失敗!\n");
        return FALSE;
    }

    *pElement = PQueue->pBase[PQueue->front];       //先進先出
    PQueue->front = (PQueue->front+1) % PQueue->maxSize; //移到下一位置

    return TRUE;
}

//遍歷佇列
void queueTraverse(queue *PQueue)
{
    int i = PQueue->front;           //從頭開始遍歷
    printf("遍歷佇列:\n");
    while(i != PQueue->rear)         //如果沒有到達rear位置,就迴圈
    {
        printf("%d  ", PQueue->pBase[i]);
        i = (i+1) % PQueue->maxSize;              //移到下一位置
    }
    printf("\n");
}

int main()
{
    //定義的指標必須分配動態記憶體空間;
    queue *pQueue=malloc(sizeof(queue));
    if(OK!=initQueue(pQueue,50))
    {
        printf("佇列初始化失敗.\n");
        return -1;
    }
    queueTraverse(pQueue);

    //給佇列賦值;
    int i;
    for(i=0;i<21;i++)
    {
        enQueue(pQueue,i);
    }
    queueTraverse(pQueue);

    //進列;
    enQueue(pQueue,10);
    queueTraverse(pQueue);

    //出列;
    ElemType *pElement=malloc(sizeof(ElemType));
    deQueue(pQueue,pElement);
    queueTraverse(pQueue);

    //獲取佇列長度;
    int length=getQueueLen(pQueue);
    printf("length=%d\n",length);

    //銷燬佇列;
    destroyQueue(pQueue);
    free(pElement);

    return 0;
}

結果:

遍歷佇列:

遍歷佇列:
0  1  2  3  4  5  6  7  8  9  10  11  12  13  14  15  16  17  18  19  20  
遍歷佇列:
0  1  2  3  4  5  6  7  8  9  10  11  12  13  14  15  16  17  18  19  20  10  
遍歷佇列:
1  2  3  4  5  6  7  8  9  10  11  12  13  14  15  16  17  18  19  20  10  
length=21