【數據結構基礎筆記】【隊列】

代碼參考《妙趣橫生的算法.C語言實現》

文章目錄

  • 前言
    • 1、隊列定義
    • 2、創建一個隊列
    • 3、入隊列
    • 4、出隊列
    • 5、銷毀一個隊列
    • 6、循環隊列的概念
    • 7、循環隊列的實現
    • 8、實例分析


前言

本章總結:鏈隊列定義,創建,出隊入隊操作,銷毀操作;循環隊列的定義以及循環隊列的一些基本操作


1、隊列定義

隊列是一種先進先出的線性表(FIFO),它要求所有的數據從隊列的一端進入,從隊列的另一端離開。
在隊列中,允許插入數據的一端角隊尾,允許數據離開的一端叫做隊頭。
在這里插入圖片描述
隊列是一個線性表,既可以是一個順序表也可以是一個鏈表。這里重點介紹用鏈表實現一個隊列。

typedef char ElemType ;
//隊列元素類,隊列中的每個元素都是QNode類
typedef struct QNode{ElemType data;			//隊列結點的數據域struct QNode* next;		//隊列結點的指針域
}QNode, *QueuePtr;typedef struct {QueuePtr front;			//隊頭指針,用來存放隊頭元素的地址QueuePtr rear;			//隊尾指針,用來存放隊尾元素的地址
}LinkQueue;
//這里定義得隊列是一個鏈隊列,隊列之間的元素由指針相連,所以只要掌握了隊列的隊頭指針和隊尾指針,就可以對隊列進行各種

2、創建一個隊列

創建一個隊列要完成兩步:
1、在內存中創建一個頭結點,但該頭結點不是用來存放數據的,而是為了操作方便人為添加的。
2、將隊列的頭指針和尾指針都指向這個生成的頭結點,此時隊列中沒有任何隊列元素,該隊列為空隊列。
這樣判斷隊列為空的條件就是頭指針front和尾指針rear都同時指向頭結點。

//創建一個空隊列
void InitQueue(LinkQueue* q)
{q->front = q->rear = (QueuePtr)malloc(sizeof(QNode));		//初始化一個隊列指針大小的空間,并將地址傳給頭指針和尾指針if (!q->front){printf("內存分配失敗");exit(0);}q->front->next = NULL;		//頭結點指針域指向空
}

此時空隊列的狀態如下:
在這里插入圖片描述

3、入隊列

入隊列就是講一個QNode類型的結點從隊列尾部進入隊列。
每當一個隊列元素插入隊列,隊列的尾指針都要進行修改。
隊頭的指針不改變。

//入隊列
void EnQueue(LinkQueue* q,ElemType elem)
{QueuePtr p;p = (QueuePtr)malloc(sizeof(QNode));		//創建一個隊列元素結點,并將地址傳給指針pif (p == NULL){printf("分配內存失敗");exit(0);}p->data = elem;			//將數據elem放到隊列結點data域中p->next = NULL;q->rear->next = p;		//從隊尾插入元素q->rear = p;			//修改隊尾指針,注意,此時隊尾指針指向空(q->rear->next = p->next =NULL)
}

入隊列操作流程:
在這里插入圖片描述

4、出隊列

出隊列操作就是將隊列中的元素從隊列的頭部移除。每次從隊列中一出數據時,隊頭指針front不改變,但是頭結點的next指針要發生改變。隊尾指針rear只有在(隊頭即隊尾)的情況下才會改變,否則也不改變。

//出隊列
void DeQueue(LinkQueue* q, ElemType *elem)
{QueuePtr p;//如果隊列不為空,刪除q的隊頭元素,用e返回其值if (q->front == q->rear) return;		//隊列為空,返回p = q->front->next;				//p指向隊列的第一個元素*elem = p->data;				//將隊首元素數據傳給eq->front->next = p->next;		//刪除當前頭結點if (q->rear == p) q->rear = q->front;		//如果此時隊列為空,則修改隊尾指針free(p);						//將原本隊頭結點銷毀
}

效果如下:
1、當隊伍中存在超過1個元素
在這里插入圖片描述
2、當隊伍中只有一個元素時
在這里插入圖片描述

5、銷毀一個隊列

由于隊列建立在內存動態區(堆內存),因此當一個隊列不再有用時,應當把它及時銷毀掉,以免占用內存空間得不到釋放導致內存泄漏。
釋放一塊內存要做兩點:1.釋放指向它的指針。2.將該指針指向空

void DestroyQueue(LinkQueue* q)
{while (q->front)			//如果隊列頭指針還存在{q->rear = q->front->next;	//q->rear指向q->front的后繼結點free(q->front);				//釋放q->front,此時q->rear應該指向NULLq->front = q->rear;}
}

6、循環隊列的概念

用順序表實現的隊列稱為循環隊列,此隊列的空間是可以循環使用的。

循環隊列一般來說有固定的容量。

如果不斷地有元素入隊列,同時又不斷地有元素出隊列,那么對于一般的鏈隊列,只要隊列不為空,頭指針front和尾指針rear都不會改變,只有頭指針的next指針和尾指針的前一個結點的next指針會發生變化,而且鏈隊列的長度也會隨著入出度列元素而不斷變化。

循環隊列,容量固定,隊頭指針和隊尾指針都可以隨著元素的入出隊列而發生改變,這樣循環隊列邏輯上就是一個環形的存儲空間,只要隊列中有空單元未使用,就可以向隊列中存放元素

所以循環隊列可以作為緩沖池存儲結構來存放數據。
在這里插入圖片描述
該隊列總容量為8B,實際長度為5B。這里規定循環隊列頭指針front始終指向隊頭元素,尾指針rear始終指向隊尾元素的下一個空間。
這里隊頭元素:f,隊尾元素:b,該隊列實際可用空間為7B。
在這里插入圖片描述
將隊首元素f出隊列,在隊尾加入元素a,形成上面隊列。

所以,入隊列操作就是想rear指向的空間賦值,rear再指向隊尾元素的下一個空間。

出隊列就是將隊頭指針front向上移一個單元。整個循環隊列邏輯上就是一個首尾相接的環形緩沖區。

7、循環隊列的實現

現實中只有線性的存儲單元,不存在環形存儲單元。

只需要注意rear不斷加1后超過循環隊列的地址范圍,采用取模運算處理的結果。

因此,無論是入隊列的rear+1操作還是出隊列的front+1操作,實際都是模加運算,即

(rear+1)%len 和(front+1)%len

/*****************************循環隊列******************************************/
//定義一個循環隊列
#define MAXQSIZE 100
typedef struct {ElemType* base;			//循環隊列內存分配基地址int front;				//隊頭int rear;				//隊尾
}cycleQueue;				//循環隊列類cycleQueue//初始化一個循環隊列
void InitcycleQueue(cycleQueue *q)
{q->base = (ElemType*)malloc(MAXQSIZE*sizeof(ElemType));//開辟MAXQSIZE個單元的順序表作為循環隊列的存儲空間if (!q->base){printf("循環隊列分配內存失敗");exit(0);}q->front = q->rear = 0;		//空隊列,front和rear都指向0號單元}
//入隊列操作
void EncycleQueue(cycleQueue* q, ElemType elem)
{if ((q->rear + 1) % MAXQSIZE == q->front)	return;	//循環隊列已滿q->base[q->rear] = elem;		//將元素elem入隊列,q->base為順序表的額首地址q->rear = (q->rear + 1) % MAXQSIZE;		//隊尾指針+1,注意這里的全部都是模加運算
}
//出隊列操作
void DecycleQueue(cycleQueue* q, ElemType* elem)
{if (q->front == q->rear)	return;				//循環隊列為空*elem = q->base[q->front];						//取出隊頭元素q->front = (q->front + 1) % MAXQSIZE;			//隊頭指針+1
}

8、實例分析

實現一個鏈隊列,任意輸入一串字符,以@為結束標志,然后將隊列中的元素逐一取出,打印出來

#include "stdio.h"
#include "malloc.h"
#include "conio.h"
#include <stdlib.h>
#include <math.h>
typedef char ElemType ;
/*****************************鏈隊列******************************************/
//隊列元素類,隊列中的每個元素都是QNode類
typedef struct QNode{ElemType data;			//隊列結點的數據域struct QNode* next;		//隊列結點的指針域
}QNode, *QueuePtr;typedef struct {QueuePtr front;			//隊頭指針,用來存放隊頭元素的地址QueuePtr rear;			//隊尾指針,用來存放隊尾元素的地址
}LinkQueue;
//這里定義得隊列是一個鏈隊列,隊列之間的元素由指針相連,所以只要掌握了隊列的隊頭指針和隊尾指針,就可以對隊列進行各種操作。、//創建一個空隊列
void InitQueue(LinkQueue* q)
{q->front = q->rear = (QueuePtr)malloc(sizeof(QNode));		//初始化一個隊列指針大小的空間,并將地址傳給頭指針和尾指針if (!q->front){printf("內存分配失敗");exit(0);}q->front->next = NULL;		//頭結點指針域指向空
}
//入隊列
void EnQueue(LinkQueue* q,ElemType elem)
{QueuePtr p;p = (QueuePtr)malloc(sizeof(QNode));		//創建一個隊列元素結點,并將地址傳給指針pif (p == NULL){printf("分配內存失敗");exit(0);}p->data = elem;			//將數據elem放到隊列結點data域中p->next = NULL;q->rear->next = p;		//從隊尾插入元素q->rear = p;			//修改隊尾指針,注意,此時隊尾指針指向空(q->rear->next = p->next =NULL)
}
//出隊列
void DeQueue(LinkQueue* q, ElemType *elem)
{QueuePtr p;//如果隊列不為空,刪除q的隊頭元素,用e返回其值if (q->front == q->rear) return;		//隊列為空,返回p = q->front->next;				//p指向隊列的第一個元素*elem = p->data;				//將隊首元素數據傳給eq->front->next = p->next;		//刪除當前頭結點if (q->rear == p) q->rear = q->front;		//如果此時隊列為空,則修改隊尾指針free(p);						//將原本隊頭結點銷毀
}//銷毀一個隊列
//釋放一塊內存要做兩點:1.釋放指向它的指針。2.將該指針指向空
void DestroyQueue(LinkQueue* q)
{while (q->front)			//如果隊列頭指針還存在{q->rear = q->front->next;	//q->rear指向q->front的后繼結點free(q->front);				//釋放q->front,此時q->rear應該指向NULLq->front = q->rear;}
}/*****************************循環隊列******************************************/
//定義一個循環隊列
#define MAXQSIZE 100
typedef struct {ElemType* base;			//循環隊列內存分配基地址int front;				//隊頭int rear;				//隊尾
}cycleQueue;				//循環隊列類cycleQueue//初始化一個循環隊列
void InitcycleQueue(cycleQueue *q)
{q->base = (ElemType*)malloc(MAXQSIZE*sizeof(ElemType));//開辟MAXQSIZE個單元的順序表作為循環隊列的存儲空間if (!q->base){printf("循環隊列分配內存失敗");exit(0);}q->front = q->rear = 0;		//空隊列,front和rear都指向0號單元}
//入隊列操作
void EncycleQueue(cycleQueue* q, ElemType elem)
{if ((q->rear + 1) % MAXQSIZE == q->front)	return;	//循環隊列已滿q->base[q->rear] = elem;		//將元素elem入隊列,q->base為順序表的額首地址q->rear = (q->rear + 1) % MAXQSIZE;		//隊尾指針+1,注意這里的全部都是模加運算
}
//出隊列操作
void DecycleQueue(cycleQueue* q, ElemType* elem)
{if (q->front == q->rear)	return;				//循環隊列為空*elem = q->base[q->front];						//取出隊頭元素q->front = (q->front + 1) % MAXQSIZE;			//隊頭指針+1
}//測試函數
int main()
{ElemType e;LinkQueue q;InitQueue(&q);		//初始化一個隊列qprintf("請輸入一串字符到隊列中\n");scanf("%c",&e);while (e != '@'){EnQueue(&q,e);scanf("%c", &e);}printf("隊列為:\n");while (q.front != q.rear){DeQueue(&q, &e);printf("%c",e);}printf("\n");DestroyQueue(&q);		//銷毀隊列q_getche();return 0;
}

效果:
在這里插入圖片描述

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/news/378212.shtml
繁體地址,請注明出處:http://hk.pswp.cn/news/378212.shtml
英文地址,請注明出處:http://en.pswp.cn/news/378212.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

html圖片自動循環輪播圖,js實現圖片無縫循環輪播

本文實例為大家分享了js實現圖片無縫循環輪播的具體代碼&#xff0c;供大家參考&#xff0c;具體內容如下代碼如下Document#container{overflow:hidden;width:400px;height:300px;margin:auto;}#front,#container{display:flex;flex-direction:row;}#container img{width:400px…

五、json模塊

一、json模塊的介紹 json模塊是Python自帶的模塊&#xff0c;用于json和Python數據之間的相互轉換 Json與Python數據類型的對應關系 JsonPythonobjectdictarrayliststringstrnumber(int)int,longnumber(real)floattrueTruefalseFalsenullNone [#中括號括起來的&#xff0c;對…

Android開發和調試必備工具-SDK Tools

原文鏈接&#xff1a;http://android.eoe.cn/topic/android_sdk SDK Tools是Android SDK的一個可下載部分&#xff0c;它包括Android SDK的開發和調試的所有工具。 如果你剛剛了解SDK&#xff0c;你可以從SDK starter package下載最新版本的SDK。 如果你已經在使用SDK&#xff…

strictmath_Java StrictMath ceil()方法與示例

strictmathStrictMath類ceil()方法 (StrictMath Class ceil() method) ceil() method is available in java.lang package. ceil()方法在java.lang包中可用。 ceil() method is used to return the least or smallest value of the double type value which is greater than or…

web應用之文件上傳

一、Jakart:Jakart文件上傳&#xff1a;&#xff08;推薦使用&#xff09; import java.io.File;import java.io.IOException;import java.util.List; import javax.servlet.ServletException;import javax.servlet.http.HttpServlet;import javax.servlet.http.HttpServletReq…

【數據結構基礎筆記】【樹】

代碼參考《妙趣橫生的算法.C語言實現》 文章目錄前言1、樹的概念2、二叉樹3、二叉樹的遍歷4、創建二叉樹5、實例分析前言 本章總結&#xff1a;樹的概念、二叉樹的創建、遍歷 1、樹的概念 樹結構是以分支關系定義得一種層次結構。 樹的定義&#xff1a;樹是由n(n>0)個結點…

可以自動撐起的html樣式,好好玩:CSS3抖動樣式CSS Shake讓你的網頁酷炫起來

之前在一些網站發現了一個好玩的樣式&#xff0c;就是鼠標移到網站LOGO上&#xff0c;logo會自動抖動起來&#xff0c;顯得非常炫酷。我也是十分感興趣。自從本站新添加了一個視覺設計的分類之后&#xff0c;我也是想起來有個抖動CSS樣式CSS Shake&#xff0c;所以今天給小伙伴…

linux技巧----查找某個正在執行的腳本

如果在機器上發現有執行的腳本&#xff0c;卻不知道在哪&#xff0c;可以這樣找 例如 # netstat -ltnp Active Internet connections (only servers) Proto Recv-Q Send-Q Local Address Foreign Address State PID/Program name tcp …

成功溝通的六要素

溝通在我們的生活、工作中必不可少&#xff0c;成功的溝通有助于事業成功&#xff0c;家庭美滿&#xff01;下面分享一篇關于溝通的文章&#xff0c;成功溝通六要素&#xff1a; 當蜘蛛網連接起來&#xff0c;可以捆住一頭獅子。——埃塞俄比亞諺語 與他人合作使我們可以實現比…

java中intvalue_Java Number intValue()方法與示例

java中intvalueNumber類intValue()方法 (Number Class intValue() method) intValue() method is available in java.lang package. intValue()方法在java.lang包中可用。 intValue() method is used to return the value denoted by this Number object converted to type int…

爬蟲項目(一)---采集最近一日世界各國的疫情數據信息

該內容出自黑馬程序員教程 采集最近一日世界各國疫情數據 步驟&#xff1a; 發送請求&#xff0c;獲取疫情首頁從疫情首頁中提取最近一日各國疫情字符串從最近一日各國疫情字符串中提取json格式字符串把json格式字符串轉換為Python類型把Python類型的數據&#xff0c;以json…

【數據結構基礎應用】【順序表】

代碼參考《妙趣橫生的算法.C語言實現》、《劍指OFFER 名企面試官精講典型編程題 第2版》等 文章目錄前言1、合并兩個順序表前言 本章總結在看書過程中的一些關于順序表的算法題并可能含有一些自己的一些疑問。題目數量不定&#xff0c;隨閱歷增加而增加&#xff1b; 1、合并兩…

html上下滾動切換頂端tab,jQuery實現Tab菜單滾動切換的方法

本文實例講述了jQuery實現Tab菜單滾動切換的方法。分享給大家供大家參考。具體如下&#xff1a;這是一款jQuery實現讓你的Tab菜單滾動的代碼,先運行一下看看效果咋樣?是不是超不錯,讓你的網頁變得靈動起來,不再靜止,學習jquery的朋友也可作為范例來參考吧.運行效果截圖如下&am…

[轉載]十四步實現擁有強大AI的五子棋游戲

又是本人一份人工智能作業……首先道歉&#xff0c;從Word貼到Livewrter&#xff0c;好多格式沒了&#xff0c;也沒做代碼高亮……大家湊活著看……想做個好的人機對弈的五子棋&#xff0c;可以說需要考慮的問題還是很多的&#xff0c;我們將制作擁有強大AI五子棋的過程分為十四…

Java BigDecimal plus()方法與示例

BigDecimal Class plus()方法 (BigDecimal Class plus() method) Syntax: 句法&#xff1a; public BigDecimal plus();public BigDecimal plus(MathContext ma_co);plus() method is available in java.math package. plus()方法在java.math包中可用。 plus() method is used…

爬蟲項目(二)---采集從03月02號以來的世界各國疫情數據

該內容出自黑馬程序員教程 采集從03月02號以來的世界各國疫情數據 步驟&#xff1a; Ⅰ&#xff0c;重構項目(一)的代碼&#xff0c;以提高擴展性 把功能封裝到一個類中每一個小功能變成一個方法通過run方法啟動爬蟲 import requests import re import json from bs4 impor…

【原創】StreamInsight查詢系列(二十)——查詢模式之檢測間隙事件

上篇文章介紹了查詢模式中如何檢測異常事件&#xff0c;這篇博文將介紹StreamInsight中如何檢測間隙事件。 測試數據準備 為了方便測試查詢&#xff0c;我們首先準備一個靜態的測試數據源&#xff1a;// 創建數據源&#xff0c;要注意的是4:16和4:30之間存在的事件間隙 var sou…

git 項目過大問題解決

當項目過大時&#xff0c;git clone時會出現error: RPC failed; HTTP curl The requested URL returned error: Gateway Time-out的問題 解決方法很簡單&#xff0c;在git clone時加上--depth1即可解決 克隆的項目只包含最近的一次commit的一個分支&#xff0c;體積很小&#x…

java bitset_Java BitSet hashCode()方法及示例

java bitsetBitSet類hashCode()方法 (BitSet Class hashCode() method) hashCode() method is available in java.util package. hashCode()方法在java.util包中可用。 hashCode() method is used to retrieve hash code for this bit set (BitSet). hashCode()方法用于檢索此位…

【數據結構基礎應用】【查找和排序算法】

代碼參考《妙趣橫生的算法.C語言實現》 文章目錄前言1、順序查找2、折半查找3、直接插入排序4、選擇排序5、冒泡排序6、希爾排序7、快速排序8、堆排序9、排序算法性能比較10、所有算法的code&#xff08;C語言&#xff09;前言 本章總結查找和排序算法&#xff1a;順序查找、折…