1. 程式人生 > >佇列的基本操作-佇列的鏈式儲存結構(帶圖詳細)

佇列的基本操作-佇列的鏈式儲存結構(帶圖詳細)

什麼是佇列?        

        佇列是一種特殊的線性表,特殊之處在於它只允許在表的前端(front)進行刪除操作,而在表的後端(rear)進行插入操作,和棧一樣,佇列是一種操作受限制的線性表。進行插入操作的端稱為隊尾,進行刪除操作的端稱為隊頭。佇列中沒有元素時,稱為空佇列。

        鏈式佇列是用單鏈表的形式來表示佇列,但是要符合佇列“尾進頭出”的規則

鏈式佇列的構建:

鏈式佇列=單鏈表+佇列。

如下程式碼是對一個佇列的鏈式儲存的定義:首先定義一個構成單鏈表基本單元的結點,然後定義由指向結點的頭指標、指向結點的尾指標和表示佇列長度的變數組成的佇列

//鏈式佇列    鏈式結構+佇列
//鏈式結構體 =單鏈表的基本單元:結點 
struct Node{
    int data;//資料域 
    struct Node* next;     //指標域 
}; 
//佇列結構體=頭指標+尾指標+佇列大小 
 struct Queue{
    struct Node* front;//指向結點的頭指標 
    struct Node* rear;//指向結點的尾指標 
    int queueSize; //佇列大小/長度 
}; 

建立結點:

佇列是由一個一個結點通過指標連結起來的

//建立結點
struct Node* createNode(int data){
    struct Node* newNode=(struct Node*)malloc(sizeof(struct Node));
    newNode->next=NULL;
    newNode->data=data;
    return newNode;    
}; 

佇列的初始化:

首先使用malloc函式為佇列分配一塊記憶體,初始狀態佇列的頭指標和尾指標在一起都為空(不帶頭結點),然後設定佇列的大小為0。這樣佇列的初始化操作就完成了。

//佇列初始化
struct Queue* createQueue(){
    struct Queue* queue=(struct Queue*)malloc(sizeof(struct Queue));//分配記憶體空間 
    queue->front=queue->rear=NULL;//頭指標和尾指標在一起為空 
    queue->queueSize=0;//佇列大小為0 
    return queue;
} 

入隊操作:

準備工作:首先建立入隊函式push()傳入兩個引數,一個是需要插入那個佇列另一個是需要插入的資料。然後呼叫createNode()函式建立一個新的結點,儲存插入的資料。

準備工作完成後:先判斷佇列是否是空佇列,如果為空佇列直接將front和rear指標指向這個新建結點即可,若不為空,則將尾指標的下一個位置指向新建結點,然後再將尾指標修改為這個新建結點。(這個地方我個人感覺比較難懂,我的理解是 先告訴這個新建結點在哪裡,然後在移動rear指標到新建結點把他設為隊尾)。

最後別忘記queueSize自增,表示佇列長度的增加。

 

void push(struct Queue* queue,int data){
    struct Node* newNode=createNode(data);
    if(queue->queueSize==0)
        queue->front=newNode;
        else
        queue->rear->next=newNode;
        queue->rear=newNode;
        queue->queueSize++;
    
} 

 獲取對頭元素:

首先判斷佇列queueSize是否為0如果為0說明佇列為空,如果不為空直接返回佇列頭指標的data值。

//獲取對頭元素
int queryFront(struct Queue* queue) {
    if(queue->queueSize==0){
        printf("佇列為空無法獲取對頭元素");
        printf("\n"); 
        return -1; 
    }
    return queue->front->data;
}

判斷佇列是否為空:

 程式碼很簡單就不一一解釋了。

//判斷佇列是否為空
int empty(struct Queue* queue){
    if(queue->queueSize==0)
    return 0;
    else
    return 1;
} 

出隊操作:

新建頭結點指標指向佇列front指標所指結點的下一個位置(因為出隊操作是在對頭進行的),然後釋放原來的隊頭結點,最後設定這個新的頭結點為隊頭。最後佇列的大小減1.

 

 

//出隊操作
void pop (struct Queue* queue){
    if(queue->queueSize==0){

    printf("佇列為空不能出隊");
    exit(0);
     }else{
         struct Node* newFrontNode=queue->front->next;
         free(queue->front); 
         queue->front=newFrontNode;
         queue->queueSize--;
     }
}

 最後附上完整程式碼:

#include <stdio.h>
#include <stdlib.h>
//鏈式佇列    鏈式結構+佇列
//鏈式結構體 =單鏈表的基本單元:結點 
struct Node{
    int data;//資料域 
    struct Node* next;     //指標域 
}; 
//佇列結構體=頭指標+尾指標+佇列大小 
 struct Queue{
    struct Node* front;//指向結點的頭指標 
    struct Node* rear;//指向結點的尾指標 
    int queueSize; //佇列大小/長度 
}; 
//建立結點
struct Node* createNode(int data){
    struct Node* newNode=(struct Node*)malloc(sizeof(struct Node));
    newNode->next=NULL;
    newNode->data=data;
    return newNode;    
}; 
//佇列初始化
struct Queue* createQueue(){
    struct Queue* queue=(struct Queue*)malloc(sizeof(struct Queue));//分配記憶體空間 
    queue->front=queue->rear=NULL;//頭指標和尾指標在一起為空 
    queue->queueSize=0;//佇列大小為0 
    return queue;
} 
//入隊
void push(struct Queue* queue,int data){
    struct Node* newNode=createNode(data);
    if(queue->queueSize==0)
        queue->front=newNode;
        else
        queue->rear->next=newNode;
        queue->rear=newNode;
        queue->queueSize++;
    
} 
//獲取對頭元素
int queryFront(struct Queue* queue) {
    if(queue->queueSize==0){
        printf("佇列為空無法獲取對頭元素");
        printf("\n"); 
        return -1; 
    }
    return queue->front->data;
}
//判斷佇列是否為空
int empty(struct Queue* queue){
    if(queue->queueSize==0)
    return 0;
    else
    return 1;
} 
//出隊操作
void pop (struct Queue* queue){
    if(queue->queueSize==0){

    printf("佇列為空不能出隊");
    exit(0);
     }else{
         struct Node* newFrontNode=queue->front->next;
         free(queue->front); 
         queue->front=newFrontNode;
         queue->queueSize--;
     }
}
int main(){
    struct Queue* myQueue=createQueue();
    push(myQueue,1);
    push(myQueue,2);
    push(myQueue,3);
    while(empty(myQueue)){
        printf("%d\t",queryFront(myQueue));
        pop(myQueue);
    }
    printf("\n");
    system("pause");
return 0;
}