国产 无码 综合区,色欲AV无码国产永久播放,无码天堂亚洲国产AV,国产日韩欧美女同一区二区

【數(shù)據(jù)結(jié)構(gòu)和算法】--隊列

這篇具有很好參考價值的文章主要介紹了【數(shù)據(jù)結(jié)構(gòu)和算法】--隊列。希望對大家有所幫助。如果存在錯誤或未考慮完全的地方,請大家不吝賜教,您也可以點擊"舉報違法"按鈕提交疑問。

隊列的概念及結(jié)構(gòu)

隊列是只允許在一端進行插入數(shù)據(jù)操作,在另一端進行刪除數(shù)據(jù)操作的特殊線性表,隊列具有先進先出FIFO(First In First Out) 的原則。

  • 入隊列:進行插入操作的一端稱為隊尾。
  • 出隊列:進行刪除操作的一端稱為隊頭。

隊列結(jié)構(gòu)聯(lián)想起來也非常簡單,如其名,隊列就相當于銀行辦理業(yè)務(wù)的柜臺前一條長長的隊伍,排在隊伍前面的人(隊頭)可以先辦理,而在隊伍最后面的人(隊尾)只能最后辦理,如果繼續(xù)有人來辦理業(yè)務(wù)就只能排在隊尾,這樣的模式就是隊列且遵循隊頭出隊列,隊尾入隊列的原則。結(jié)構(gòu)大致如下:

【數(shù)據(jù)結(jié)構(gòu)和算法】--隊列,數(shù)據(jù)結(jié)構(gòu)和算法,算法,數(shù)據(jù)結(jié)構(gòu)

隊列的實現(xiàn)

隊列的實現(xiàn)同樣有兩種方式–數(shù)組隊列,鏈式隊列

  1. 數(shù)組隊列:
    如果用數(shù)組實現(xiàn)隊列:這樣隊頭就只能指向下標為0的位置,那么隊尾就指向隊列最后一個元素的后一個的下標,基于此結(jié)構(gòu),想要出隊操作,時間復(fù)雜度就會升高為O(N)且十分不方便。因為每當要將下標為0的元素出隊,后面的所有元素就要前移并改變隊尾指向。大致如下:

【數(shù)據(jù)結(jié)構(gòu)和算法】--隊列,數(shù)據(jù)結(jié)構(gòu)和算法,算法,數(shù)據(jù)結(jié)構(gòu)

還有一點就是,如果使用數(shù)組隊列,在前期有大量數(shù)據(jù)入隊列,動態(tài)開辟了很大的空間,到后期可能很多數(shù)據(jù)都出了隊列但動態(tài)開辟的空間并不能釋放,那就造成了嚴重的空間浪費。

  1. 鏈式隊列:
    如果使用雙向鏈表: 這與棧為什么不用雙向鏈表實現(xiàn)一個道理,雖然可以實現(xiàn),且入隊/出隊的時間復(fù)雜度都為O(1)但結(jié)構(gòu)較為復(fù)雜,實現(xiàn)起來并不是很實用;
    那么我們這時會選擇結(jié)構(gòu)更優(yōu)得單鏈表,雖說單鏈表尾插得時間復(fù)雜度是O(N),但我們可以定義一個變量(QNode* ptail)來記錄單鏈表的尾節(jié)點,這樣每次入隊時便不用再遍歷單鏈表找尾節(jié)點,時間復(fù)雜度也降為O(1)。結(jié)構(gòu)如下:

【數(shù)據(jù)結(jié)構(gòu)和算法】--隊列,數(shù)據(jù)結(jié)構(gòu)和算法,算法,數(shù)據(jù)結(jié)構(gòu)

這樣按需開辟空間,出隊列就釋放節(jié)點,進隊列新建節(jié)點,也大大減少了空間的浪費。我們便可如下定義隊列的每個節(jié)點:

typedef int QDataType;
//隊列節(jié)點
typedef struct QueueNode
{
    QDataType val;
    struct QueueNode* next;//鏈接下一個節(jié)點的指針
}QNode;

因為我們要記錄隊列的頭(QNode* phead)和尾(QNode* ptail)(下文稱這兩個指針為頭指針和尾指針),且基本每個函數(shù)都要用到這兩個變量,甚至一些函數(shù)還要修改這兩個變量對應(yīng)的值,那就不得不傳二級指針了,這也就大大增加了代碼的難度!為了解決這個問題,我們可以定義一個結(jié)構(gòu)體,并將這兩個變量放到結(jié)構(gòu)體中,每次函數(shù)調(diào)用時,只需傳這個結(jié)構(gòu)體地址即可;
為了方便統(tǒng)計隊列里面的節(jié)點數(shù),我們通常還會定義一個整型變量size,有元素出隊列時size--,入隊列時size++
此結(jié)構(gòu)體定義方式如下:

typedef struct Queue
{
    QNode* phead;
    QNode* ptail;
    int size;
}Queue;

初始化

初始時隊列中無節(jié)點,所以pq->size = 0,頭指針(pq->phead = NULL)尾指針(pq->ptail = NULL)都指向空。

//初始化
void QueueInit(Queue* pq)
{
	assert(pq);
	pq->size = 0;
	pq->phead = pq->ptail = NULL;
}

入隊

入隊操作首先要新建一個節(jié)點(類型為QNode),然后通過尾指針指向的節(jié)點鏈接此節(jié)點pq->ptail->next = newnode),并更新尾指針的指向pq->ptail = newnode),將記錄節(jié)點數(shù)的值加1(pq->size++)。
在鏈接時還要考慮到隊列為空的情況,此情況下直接將頭/尾指針指向新建的節(jié)點(pq->ptail = pq->phead = newnode)。

//入隊列
void QueuePush(Queue* pq, QDataType x)
{
	assert(pq);
	//新建節(jié)點
	QNode* newnode = (QNode*)malloc(sizeof(QNode));
	if (newnode == NULL)
	{
		perror("QueuePush()::malloc");
		return;
	}
	//新建的節(jié)點初始化
	newnode->next = NULL;
	newnode->val = x;
	//判斷,鏈接
	if (pq->ptail == NULL)
	{
	    //1.原隊列無節(jié)點
		pq->ptail = pq->phead = newnode;
	}
	else
	{
	    //2.原隊列已有節(jié)點
		pq->ptail->next = newnode;
		pq->ptail = newnode;
	}
	pq->size++;
}

出隊

出隊列操作首先要確保隊列有節(jié)點才能出隊,那么斷言一下就可(assert(pq->phead);)。需要注意的是出隊是頭刪,可以先定義變量記錄頭節(jié)點QNode* del = pq->phead;),然后再將頭指針指向下一個節(jié)點phead = phead->next;),最后將原頭節(jié)點釋放free(del);),并將記錄節(jié)點數(shù)的值減1pq->size--)。
當隊列只有一個節(jié)點時,刪除后隊尾和隊頭指針都應(yīng)該指向空,但上述操作并不能達到此效果,所以要單獨判斷一下,將尾指針指向空。

//出隊列
void QueuePop(Queue* pq)
{
	assert(pq);
	//隊列不為空
	assert(pq->phead);
	QNode* del = pq->phead;//記錄頭節(jié)點
	pq->phead = pq->phead->next;//頭指針重定向
	free(del);//釋放原頭節(jié)點
	del = NULL;
	//隊列是否被刪空判斷
	if (pq->phead == NULL)
		pq->ptail = NULL;
	pq->size--;
}

其他一些隊列函數(shù)

  1. 隊列有效數(shù)據(jù)個數(shù):
    上面也講過pq->size記錄的就是隊列的有效數(shù)據(jù)個數(shù)
//數(shù)據(jù)個數(shù)
int QueueSize(Queue* pq)
{
	assert(pq);
	return pq->size;
}
  1. 隊列是否為空:
    兩種判斷方法:1.當頭指針指向NULL,2.pq->size的值為0。
//隊列是否為空
bool QueueEmpty(Queue* pq)
{
	assert(pq);
	return pq->phead == NULL;
	//return pq->size == 0;
}

  1. 返回隊頭數(shù)據(jù):
    首先要判斷隊列不為空,然后返回頭指針指向的節(jié)點的val即可。
//返回隊頭數(shù)據(jù)
QDataType QueueFront(Queue* pq)
{
	assert(pq);
	assert(pq->phead);
	return pq->phead->val;
}
  1. 返回隊尾數(shù)據(jù):
    同上,首先要判斷隊列不為空,然后返回尾指針指向的節(jié)點的val即可。
//返回隊尾數(shù)據(jù)
QDataType QueueBack(Queue* pq)
{
	assert(pq);
	assert(pq->phead);
	return pq->ptail->val;
}
  1. 釋放隊列空間:
    遍歷隊列直到頭指針指向空,每遍歷一次釋放一個節(jié)點,最后將頭/尾指針指空,pq->size0。
//釋放
void QueueDetroy(Queue* pq)
{
	assert(pq);
	QNode* cur = pq->phead;
	//遍歷,釋放
	while (cur)
	{
	    //記錄下一個節(jié)點地址
		QNode* next = cur->next;
		free(cur);
		cur = next;
	}
	pq->phead = pq->ptail = NULL;
	pq->size = 0;
}

小結(jié)

  • 隊列是一種先進先出的結(jié)構(gòu),與棧相反;
  • 隊列是頭部刪除尾部插入一般使用鏈表實現(xiàn),且與棧結(jié)構(gòu)一樣不支持隨機訪問;
  • 在實現(xiàn)隊列時一般定義兩個結(jié)構(gòu)體,一個結(jié)構(gòu)體用來記錄每個節(jié)點中所需要的值,另一個用來記錄隊列的隊頭,隊尾和節(jié)點數(shù)。第二個結(jié)構(gòu)體的使用避免了二級指針,且在函數(shù)調(diào)用時一般傳第二個結(jié)構(gòu)體的地址。

隊列相關(guān)題目

  1. 下面關(guān)于棧和隊列的說法中錯誤的是( A B
    A.隊列和棧通常都使用鏈表實現(xiàn)
    B.隊列和棧都只能從兩端插入、刪除數(shù)據(jù)
    C.隊列和棧都不支持隨機訪問和隨機插入
    D.隊列是“先入先出”,棧是“先入后出”

這題主要考察對隊列和棧的性質(zhì)的區(qū)分,思路如下:

  • A錯誤:是尾部插入和刪除,一般使用順序表實現(xiàn),隊列是頭部刪除尾部插入,一般使用鏈表實現(xiàn)

  • B錯誤:是后進先出,尾部插入和刪除;隊列是先進先出,尾部插入頭部刪除

  • C正確:棧只能訪問棧頂元素,不支持隨機訪問,隊列也不支持

  • D正確:棧和隊列的特性

關(guān)于隊列還有一個知識點就是循環(huán)隊列,因其結(jié)構(gòu)復(fù)雜就單獨拿出來講。文章來源地址http://www.zghlxwxcb.cn/news/detail-753800.html

到了這里,關(guān)于【數(shù)據(jù)結(jié)構(gòu)和算法】--隊列的文章就介紹完了。如果您還想了解更多內(nèi)容,請在右上角搜索TOY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!

本文來自互聯(lián)網(wǎng)用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務(wù),不擁有所有權(quán),不承擔相關(guān)法律責任。如若轉(zhuǎn)載,請注明出處: 如若內(nèi)容造成侵權(quán)/違法違規(guī)/事實不符,請點擊違法舉報進行投訴反饋,一經(jīng)查實,立即刪除!

領(lǐng)支付寶紅包贊助服務(wù)器費用

相關(guān)文章

  • 算法與數(shù)據(jù)結(jié)構(gòu)(四)--隊列

    算法與數(shù)據(jù)結(jié)構(gòu)(四)--隊列

    隊列是另一種特殊的表,這種表只在表首(也稱為隊首)進行刪除操作,只在表尾進行插入操作。 隊列的修改是按 先進先出 的規(guī)則進行的,所以隊列又稱為先進先出表,F(xiàn)irst In First Out,簡稱FIFO表。映射到生活中就是排隊的隊伍。 如示意圖所示,a(1)就是隊首元素,a(n)就是隊

    2024年02月15日
    瀏覽(29)
  • 數(shù)據(jù)結(jié)構(gòu)與算法04:隊列

    數(shù)據(jù)結(jié)構(gòu)與算法04:隊列

    目錄 什么是隊列? 循環(huán)隊列 雙端隊列 阻塞隊列 隊列的應(yīng)用場景 每日一練 在 上一篇文章 中講述了棧:先進后出就是棧,隊列剛好相反, 先進先出的數(shù)據(jù)結(jié)構(gòu)就是隊列 ,還是拿紙箱子來舉例:隊列可以理解為一個沒有底的紙箱子,往箱子里面放書,一本一本疊上去,但是

    2024年02月06日
    瀏覽(26)
  • Python數(shù)據(jù)結(jié)構(gòu)與算法-數(shù)據(jù)結(jié)構(gòu)(列表、棧、隊列、鏈表)

    Python數(shù)據(jù)結(jié)構(gòu)與算法-數(shù)據(jù)結(jié)構(gòu)(列表、棧、隊列、鏈表)

    數(shù)據(jù)結(jié)構(gòu)是指相互之間存在這一種或者多種關(guān)系的數(shù)據(jù)元素的集合和該集合中元素之間的關(guān)系組成。 簡單來說,數(shù)據(jù)結(jié)構(gòu)就是設(shè)計數(shù)據(jù)以何種方式組織并存儲在計算機中。 比如:列表、集合與字典等都是一種數(shù)據(jù)結(jié)構(gòu)。 N.Wirth:“程序=數(shù)據(jù)結(jié)構(gòu)+算法” 數(shù)據(jù)結(jié)構(gòu)按照其 邏輯結(jié)

    2024年02月08日
    瀏覽(35)
  • 數(shù)據(jù)結(jié)構(gòu)之棧、隊列——算法與數(shù)據(jù)結(jié)構(gòu)入門筆記(四)

    數(shù)據(jù)結(jié)構(gòu)之棧、隊列——算法與數(shù)據(jù)結(jié)構(gòu)入門筆記(四)

    本文是算法與數(shù)據(jù)結(jié)構(gòu)的學習筆記第四篇,將持續(xù)更新,歡迎小伙伴們閱讀學習 。有不懂的或錯誤的地方,歡迎交流 棧是一種線性數(shù)據(jù)結(jié)構(gòu),其 只允許在固定的一端進行插入和刪除 元素操作。進行數(shù)據(jù)插入和刪除操作的一端稱為棧頂 (Top), 另一端稱為棧底 (Bottom)。棧中的

    2024年02月08日
    瀏覽(23)
  • 數(shù)據(jù)結(jié)構(gòu)與算法:棧和隊列

    數(shù)據(jù)結(jié)構(gòu)與算法:棧和隊列

    棧是一種后入先出(LIFO)的線性邏輯存儲結(jié)構(gòu)。只允許在棧頂進行進出操作。 基本操作包括:入棧(push)/出棧(pop)/獲取棧頂元素(peek)。 棧的實現(xiàn)主要有兩種: 1. 數(shù)組實現(xiàn),即順序棧 2. 鏈表實現(xiàn),即鏈式棧 無論是以數(shù)組還是以鏈表實現(xiàn),入棧、出棧的時間復(fù)雜度都是

    2024年02月11日
    瀏覽(22)
  • 數(shù)據(jù)結(jié)構(gòu)與算法-雙端隊列

    Gitee上開源的數(shù)據(jù)結(jié)構(gòu)與算法代碼庫:數(shù)據(jù)結(jié)構(gòu)與算法Gitee代碼庫 雙端隊列、隊列、棧對比 定義 特點 隊列 一端刪除(頭)另一端添加(尾) First In First Out 棧 一端刪除和添加(頂) Last In First Out 雙端隊列 兩端都可以刪除、添加 優(yōu)先級隊列 優(yōu)先級高者先出隊 延時隊列 根據(jù)

    2024年02月13日
    瀏覽(21)
  • 【數(shù)據(jù)結(jié)構(gòu)與算法】設(shè)計循環(huán)隊列

    【數(shù)據(jù)結(jié)構(gòu)與算法】設(shè)計循環(huán)隊列

    ??????? 個人主頁:簡 料 ???? 所屬專欄:C++ ???? 個人社區(qū):越努力越幸運社區(qū) ???? 簡? ? ?? 介: 簡料簡料,簡單有料~在校大學生一枚,專注C/C++/GO的干貨分享,立志成為您的好幫手 ~ C/C++學習路線 (點擊解鎖) ?? C語言階段(已結(jié)束) ?? 數(shù)據(jù)結(jié)構(gòu)與算法(ing) ?

    2024年01月17日
    瀏覽(21)
  • 【數(shù)據(jù)結(jié)構(gòu)與算法】隊列的實現(xiàn)

    【數(shù)據(jù)結(jié)構(gòu)與算法】隊列的實現(xiàn)

    ?? 作者:@ 阿亮joy. ?? 專欄:《數(shù)據(jù)結(jié)構(gòu)與算法要嘯著學》 ?? 座右銘:每個優(yōu)秀的人都有一段沉默的時光,那段時光是付出了很多努力卻得不到結(jié)果的日子,我們把它叫做扎根 隊列:只允許在一端進行插入數(shù)據(jù)操作,在另一端進行刪除數(shù)據(jù)操作的特殊線性表,隊列具有先

    2024年02月07日
    瀏覽(52)
  • 【數(shù)據(jù)結(jié)構(gòu)與算法】03 隊列(順序隊列--循環(huán)隊列--優(yōu)先級隊列--鏈隊列)

    【數(shù)據(jù)結(jié)構(gòu)與算法】03 隊列(順序隊列--循環(huán)隊列--優(yōu)先級隊列--鏈隊列)

    隊列( queue )是一種常見的數(shù)據(jù)結(jié)構(gòu),它遵循先進先出(FIFO)的原則。隊列可以理解為一個具有兩個端點的線性數(shù)據(jù)結(jié)構(gòu),其中一個端點稱為\\\"隊尾\\\"(rear),用于插入新元素,另一個端點稱為\\\"隊首\\\"(front),用于移除元素。新元素被插入到隊尾,而最早插入的元素總是在隊

    2024年02月08日
    瀏覽(21)
  • 【Java數(shù)據(jù)結(jié)構(gòu) -- 隊列:隊列有關(guān)面試oj算法題】

    【Java數(shù)據(jù)結(jié)構(gòu) -- 隊列:隊列有關(guān)面試oj算法題】

    只允許在一端進行插入數(shù)據(jù)操作,在另一端進行刪除數(shù)據(jù)操作得特殊線性表,隊列是 先進先出 ,入隊:進行插入操作得一端稱為 隊尾(rear) ,出隊:進行刪除操作的一端稱為 隊頭(front) 。隊列Queue是個接口, 底層通過鏈表實現(xiàn)的 。 boolean offer(E e) – 入隊列 E poll() – 出隊

    2024年01月25日
    瀏覽(22)

覺得文章有用就打賞一下文章作者

支付寶掃一掃打賞

博客贊助

微信掃一掃打賞

請作者喝杯咖啡吧~博客贊助

支付寶掃一掃領(lǐng)取紅包,優(yōu)惠每天領(lǐng)

二維碼1

領(lǐng)取紅包

二維碼2

領(lǐng)紅包