日本免费高清视频-国产福利视频导航-黄色在线播放国产-天天操天天操天天操天天操|www.shdianci.com

學(xué)無(wú)先后,達(dá)者為師

網(wǎng)站首頁(yè) 編程語(yǔ)言 正文

C語(yǔ)言實(shí)現(xiàn)隊(duì)列的示例詳解_C 語(yǔ)言

作者:。菀枯。 ? 更新時(shí)間: 2022-08-21 編程語(yǔ)言

前言

前一段時(shí)間,我們?cè)囍肅語(yǔ)言實(shí)現(xiàn)了數(shù)據(jù)結(jié)構(gòu)中的順序表,單鏈表,雙向循環(huán)鏈表,棧。今天我們?cè)儆肅語(yǔ)言來(lái)實(shí)現(xiàn)另一種特殊的線性結(jié)構(gòu):隊(duì)列

一. 什么是隊(duì)列

隊(duì)列是一種特殊的線性表,特殊之處在于它只允許在表的前端(head)進(jìn)行刪除操作,而在表的后端(tail)進(jìn)行插入操作,和棧一樣,隊(duì)列是一種操作受限制的線性表。進(jìn)行插入操作的端稱為隊(duì)尾,進(jìn)行刪除操作的端稱為隊(duì)頭。

這個(gè)隊(duì)列就可以理解成我們平時(shí)的排隊(duì),先進(jìn)入的先出去,與我們之前實(shí)現(xiàn)的先進(jìn)后出的棧相反。

二. 使用什么來(lái)實(shí)現(xiàn)棧

再把上次的圖拿出來(lái),我們看看是用線性表來(lái)實(shí)現(xiàn)隊(duì)列,還是鏈表比較好

不同點(diǎn) 順序表 鏈表
存儲(chǔ)空間上 物理上一定連續(xù) 邏輯上連續(xù),但物理上不一定連續(xù)
隨機(jī)訪問(wèn) 可以直接訪問(wèn)任何元素 必須從頭節(jié)點(diǎn)開(kāi)始往后尋找
任意位置插入或刪除元素 要搬移其他的元素,效率低。 只需要修改節(jié)點(diǎn)的指針指向,效率高
插入 動(dòng)態(tài)順序表,當(dāng)空間不夠時(shí)需要擴(kuò)容 無(wú)容量概念,需要就申請(qǐng),不用就釋放
應(yīng)用場(chǎng)景 元素高效存儲(chǔ),并且需要頻繁訪問(wèn) 需要在任意位置插入或者刪除頻繁

綜合上表來(lái)看,我覺(jué)得鏈表較為方便,原因如下:

1.隊(duì)列有多少元素不確定,鏈表可以做到需要就申請(qǐng),不用就釋放,較為方便

2.隊(duì)列是先進(jìn)先出,順序固定,不需要隨機(jī)訪問(wèn)。

三. 隊(duì)列的實(shí)現(xiàn)

3.1頭文件

1.包含的標(biāo)準(zhǔn)庫(kù)

#include <stdio.h>
#include <stdlib.h>
#include <stdbool.h>
#include <assert.h>

2.定義結(jié)構(gòu)體

typedef int QDateType;//隊(duì)列存儲(chǔ)數(shù)據(jù)類型

typedef struct QueueNode //隊(duì)列元素節(jié)點(diǎn)
{
	QDateType val;
	struct QueueNode* next;
}QueueNode;

typedef	struct Queue //隊(duì)列
{
	QueueNode* head;
	QueueNode* tail;
}Queue;

3.函數(shù)聲明

void QueueInti(Queue* pq);
// 隊(duì)列初始化
void QueueDestory(Queue* pq);
// 隊(duì)列的銷毀
void QueuePush(Queue* pq, QDateType x);
// 入隊(duì)
void QueuePop(Queue* pq);
// 出隊(duì)
QDateType QueueFront(Queue* pq);
// 取出隊(duì)首元素
int QueueSize(Queue* pq);
// 求隊(duì)列的長(zhǎng)度
bool QueueEmpty(Queue* pq);
// 判斷隊(duì)是否為空

3.2 函數(shù)的實(shí)現(xiàn)

1.隊(duì)列的初始化

將頭尾置為空指針即可。

void QueueInti(Queue* pq)
{
    assert(pq); //防止pq為空指針
    pq->head = pq->tail = NULL;
}

2.隊(duì)列的銷毀

遍歷隊(duì)列元素,然后將每一個(gè)元素釋放。

void QueueDestory(Queue* pq)
{
    assert(pq); //防止pq為空指針
    QueueNode* cur = pq->head;
    while (cur)
    {
        QueueNode* next = cur->next;
        free(cur);
        cur = next;
    }
    pq->tail = pq->head = NULL;
}

3.入隊(duì)

對(duì)于入隊(duì),我們首先需要去開(kāi)辟一個(gè)新的節(jié)點(diǎn)來(lái)存儲(chǔ)數(shù)據(jù),然后將這個(gè)節(jié)點(diǎn)加入到tail后即可。此時(shí)我們就要分別考慮。

1.如果為空隊(duì)列,那么我們不僅要改變tail,還要改變head的值

2.如果不為空隊(duì)列,只用改變tail即可。

void QueuePush(Queue* pq, QDateType x)
{
	assert(pq); //防止pq為空指針

	QueueNode* newNode = (QueueNode*)malloc(sizeof(QueueNode));
	if (NULL == newNode)
	{
		printf("malloc error\n");
		exit(-1);
	}
	newNode->val = x;
	newNode->next = NULL;//開(kāi)辟一個(gè)新節(jié)點(diǎn)存儲(chǔ)數(shù)據(jù)

	if (pq->tail == NULL)//判斷是否為空隊(duì)列
	{
		assert(pq->head == NULL);
		pq->head = pq->tail = newNode;
	}
	else
	{
		pq->tail->next = newNode;
		pq->tail = newNode;
	}
}

4.出隊(duì)

對(duì)于出隊(duì),我們同樣需要考慮兩種情況

  • 隊(duì)列為空,改變head的同時(shí)改變tail
  • 隊(duì)列不為空,改變head即可。
void QueuePop(Queue* pq)
{
    assert(pq);//防止pq為空指針
    assert(pq->head && pq->tail); //防止隊(duì)列為空隊(duì)列
    if (pq->head->next == NULL)
    {
        free(pq->head);
        pq->head = pq->tail = NULL;
    }
    else
    {
        QueueNode* next = pq->head->next;
        free(pq->head);
        pq->head = next;
    }
}

5. 取出隊(duì)首元素

沒(méi)啥說(shuō)的,直接訪問(wèn)頭節(jié)點(diǎn)取出即可

QDateType QueueFront(Queue* pq)
{
    assert(pq);//防止pq為空指針
    assert(pq->head && pq->tail); //防止隊(duì)列為空隊(duì)列

    return pq->head->val;
}

6.判斷是否為空隊(duì)列

我們只需要判斷頭指針是否為NULL,如果是則為空

bool QueueEmpty(Queue* pq)
{
    assert(pq);

    return pq->head == NULL;
}

7. 求隊(duì)伍長(zhǎng)度

創(chuàng)建一個(gè)變量,遍歷隊(duì)伍求長(zhǎng)度。

int QueueSize(Queue* pq)
{
    assert(pq);
    QueueNode* cur = pq->head;
    int count = 0;
    while (cur)
    {
        cur = cur->next;
        count++;
    }
    return count;
}

四.完整代碼

#include <stdio.h>
#include <stdlib.h>
#include <stdbool.h>
#include <assert.h>

typedef int QDateType;

typedef struct QueueNode
{
	QDateType val;
	struct QueueNode* next;
}QueueNode;

typedef	struct Queue
{
	QueueNode* head;
	QueueNode* tail;
}Queue;

void QueueInti(Queue* pq)
{
	assert(pq);
	pq->head = pq->tail = NULL;
}

void QueueDestory(Queue* pq)
{
	assert(pq);
	QueueNode* cur = pq->head;
	while (cur)
	{
		QueueNode* next = cur->next;
		free(cur);
		cur = next;
	}
	pq->tail = pq->head = NULL;
}

void QueuePush(Queue* pq, QDateType x)
{
	assert(pq);

	QueueNode* newNode = (QueueNode*)malloc(sizeof(QueueNode));
	if (NULL == newNode)
	{
		printf("malloc error\n");
		exit(-1);
	}
	newNode->val = x;
	newNode->next = NULL;

	if (pq->tail == NULL)
	{
		assert(pq->head == NULL);
		pq->head = pq->tail = newNode;
	}
	else
	{
		pq->tail->next = newNode;
		pq->tail = newNode;
	}

}

void QueuePop(Queue* pq)
{
	assert(pq);
	assert(pq->head && pq->tail);
	if (pq->head->next == NULL)
	{
		free(pq->head);
		pq->head = pq->tail = NULL;
	}
	else
	{
		QueueNode* next = pq->head->next;
		free(pq->head);
		pq->head = next;
	}
}

bool QueueEmpty(Queue* pq)
{
	assert(pq);

	return pq->head == NULL;
}

QDateType QueueFront(Queue* pq)
{
	assert(pq);
	assert(pq->head);

	return pq->head->val;
}

int QueueSize(Queue* pq)
{
	assert(pq);
	QueueNode* cur = pq->head;
	int count = 0;
	while (cur)
	{
		cur = cur->next;
		count++;
	}
	return count;
}

原文鏈接:https://blog.csdn.net/m0_60447315/article/details/123764859

欄目分類
最近更新