1. 程式人生 > >數據結構之鏈式隊列(C實現)

數據結構之鏈式隊列(C實現)

num 返回 創建 位置 刪除 () temp 結點 pan

技術分享

linkqueue.h
#ifndef LINKQUEUE_H
#define LINKQUEUE_H

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

typedef enum
{
    OK=0, //正確
    ERROR=1,   //出錯
    TRUE=2,  //為真
    FALSE=3   //為假
}status;

typedef int ElemType;   //宏定義隊列的數據類型

/* 鏈式隊列:是指采用鏈式存儲結構的隊列,隊列中每一個元素對應鏈表中的結點。
 * 和鏈式棧類似,一般采用單鏈表來實現鏈式隊列。
 ************************************************************
*/ // 鏈式隊列結點結構 typedef struct Node { ElemType data; //結點數據 //【負責建立隊列各結點之間的聯系,前一個結點的next指向後一個結點,形成鏈式隊列】 struct Node *next; //後繼結點 }LQNode; // 鏈式隊列結構 typedef struct { LQNode *front; //鏈式隊列的隊頭指針,總是指向隊列的頭結點(出隊一次,第二個結點變為頭結點) LQNode *rear; //鏈式隊列的隊尾指針,入隊時指向新插入結點(總是指向隊列的最後一個結點) }LinkQueue;
//創建空隊列 status initQueue(LinkQueue *pQHead); //銷毀隊列 void destroyQueue(LinkQueue *pQHead); //清空隊列 void clearQueue(LinkQueue *pQHead); //判斷隊列是否為空 status isEmpityQueue(LinkQueue *pQHead); //獲得隊列長度 int getQueueLen(LinkQueue *pQHead); //新元素入隊 [先進先出原則:在隊尾的位置插入] element-要插入元素 status enQueue(LinkQueue *pQHead,ElemType element);
//新元素出隊,同時保存出隊的元素 [先進先出原則:在隊頭的位置刪除] status deQueue(LinkQueue *pQHead,ElemType *pElement); //遍歷隊列 void queueTraverse(LinkQueue *pQHead); #endif // LINKQUEUE_H

linkqueue.c
#include "linkqueue.h"

/*********************************************************************
 * 剛開始創建空隊列時,隊列的隊頭和隊尾指針相等都指向頭結點,頭結點的數據域不存放數據
 * 第一次入隊,創建新結點,其數據域保存新插入元素,頭結點的next指向新結點,
 * 並且隊列的隊尾指針指向新結點,隊列的隊頭指針仍然指向頭結點,依次類推
 * 第一次出隊,則隊列的隊頭指針指向頭結點的next,依次類推
 *********************************************************************/

//創建空隊列: pQHead即為隊列頭結點
status initQueue(LinkQueue *pQHead)
{
    //隊列頭結點的隊頭和隊尾指針申請內存
    pQHead->front = pQHead->rear = (LQNode*)malloc(sizeof(LQNode));
    if(!pQHead->front) //檢測是否申請失敗
    {
        printf("pQHead->front malloc error!\n");
        return ERROR;
    }

    //設置頭結點指針域為空
    pQHead->front->next = NULL;

    return OK;
}

//銷毀隊列
void destroyQueue(LinkQueue *pQHead)
{
    free(pQHead->front);
    free(pQHead->rear);
    pQHead->front = pQHead->rear = NULL;
}

//清空隊列
void clearQueue(LinkQueue *pQHead)
{
    pQHead->front = pQHead->rear;
}

//判斷隊列是否為空
status isEmpityQueue(LinkQueue *pQHead)
{
    //隊頭指針與隊尾指針相等,說明隊列為空
    if(pQHead->front == pQHead->rear)
        return TRUE;

    return FALSE;
}

//獲得隊列長度
int getQueueLen(LinkQueue *pQHead)
{
    LQNode *temp = pQHead->front;
    int length = 0;
    while(temp != pQHead->rear)
    {
        ++length;
        temp = temp->next;
    }

    return length;
}

//新元素入隊:即鏈式隊列的尾結點指針,指向存放新元素的新結點
status enQueue(LinkQueue *pQHead, ElemType element)
{
    //創建新結點,並申請內存
    LQNode  *temp = (LQNode*)malloc(sizeof(LQNode));
    if(!temp)
    {
        printf("temp malloc error!\n");
        return ERROR;
    }

    temp->data = element; //將要插入元素存入新結點的數據域內
    temp->next = NULL; //隊列只能從隊尾插入所以下一個結點初始化為NULL

    //鏈式隊列元素為結點(LQNode)
    //pQHead->rear為隊列的最後一個結點,當插入新結點temp時,pQHead->rear->next = temp
    //使前一個結點的next指向新結點,建立隊列各結點之間的聯系
    pQHead->rear->next = temp; //將隊尾結點的後繼指針指向新結點,如果第一次入隊,
                      //則pQueue->rear->next相當於pQueue->front->next
    // pQHead->rear總是指向隊列的最後一個結點
    pQHead->rear = temp;    //將隊尾結點的指針指向新結點temp,temp變為最後一個結點

    return OK;
}

status deQueue(LinkQueue *pQHead,ElemType *pElement)
{
    //如果隊列為空,則返回ERRIR
    if(isEmpityQueue(pQHead)==TRUE)
    {
        printf("queue is NULL!\n");
        return ERROR;
    }

    //值入隊一次後就出隊,則pQueue->front->next==pQHead->rear->next,為第一個插入的結點
    LQNode *temp = pQHead->front->next; //初始化temp為要出隊的結點的指針

    //如果要出隊的結點為最後一個結點,使q->rear指向頭結點防止出現懸空的指針
    if(pQHead->front->next == pQHead->rear)
        pQHead->rear = pQHead->front;

    *pElement = temp->data; //將出隊的數據元素存入*e
    pQHead->front->next = temp->next; //使下一個結點成為隊頭,如果沒有下一個結點則為NULL
    free(temp); //刪除要出隊的結點
    temp = NULL;

    return OK;
}

//遍歷隊列
void queueTraverse(LinkQueue *pQHead)
{
    //如果隊列為空
    if(isEmpityQueue(pQHead)==TRUE)
    {
        printf("\nqueue is NULL!\n");
    }

    LQNode *temp = pQHead->front;

    printf("將隊列中的所有元素出隊:\n");
    while(temp != pQHead->rear)
    {

        temp = temp->next;
        printf("%d  ", temp->data);
    }
    printf("\n");
}

main.c
/*********************************************
 * C實現鏈式隊列   2017/10/26   by nieXianFeng
 *********************************************/
#include <stdio.h>
#include "linkqueue.h"

int main()
{
    int value;          //用於保存出隊的元素

    //給頭結點申請內存
    LinkQueue *pQHead= (LinkQueue*)malloc(sizeof(LinkQueue));
    if(!pQHead) //檢測是否申請失敗
    {
        printf("pQHead malloc error!\n");
        return ERROR;
    }

    //調用初始化隊列的函數
    initQueue(pQHead);
    //調用出隊函數
    enQueue(pQHead, 1);
    enQueue(pQHead, 2);
    enQueue(pQHead, 3);
    enQueue(pQHead, 4);
    enQueue(pQHead, 5);
    enQueue(pQHead, 6);
    enQueue(pQHead, 7);
    enQueue(pQHead, 8);
    //調用遍歷隊列的函數
    queueTraverse(pQHead);

    //調用出隊函數
    if(deQueue(pQHead, &value)==OK)
    {
        printf("出隊一次,元素為:%d\n", value);
    }
    queueTraverse(pQHead);
    if(deQueue(pQHead, &value)==OK)
    {
        printf("出隊一次,元素為:%d\n", value);
    }
    queueTraverse(pQHead);

    printf("隊列長度是%d\n",getQueueLen(pQHead));

    clearQueue(pQHead);   //清空隊列
    queueTraverse(pQHead);

    free(pQHead);
    pQHead = NULL;

    return 0;
}



數據結構之鏈式隊列(C實現)