上一章節針對于C語言棧結構做了解析,不清楚的可以回顧一下。
本章節主要針對于C語言的基礎數據結構隊列做以解析。
數據結構之隊列
隊列是一種特殊的 線性表 ,特殊之處在于它隻允許在表的前端(front)進行删除操作,而在表的後端(rear)進行插入操作,和棧一樣,隊列是一種操作受限制的線性表。進行插入操作的端稱為隊尾,進行删除操作的端稱為隊友。
故隊列基本操作如下:
(1)創建隊列
(2)入隊
(3)出隊
(4)判斷隊列是否為NULL
(5)獲取隊頭元素
數據結構之隊列分類根據隊列實現方式與出隊方式,我們可以把棧分為以下三種描述方式:
(1)原生數組隊列
(2)動态申請内存的數組描述(普通隊列和循環隊列)
(3)鍊式結構描述
優先隊列
原生數組描述隊列
數組描述棧,隻不過多了先進先出的限制而已,它是靜态分配的,即使用前,它的内存就已經以數組的形式分配好了,所以在使用時,需要注意隊頭隊尾的标記。
原生數組描述隊列實現試題案例:逆序整數
動态數組描述隊列
動态申請内存的數組描述不再采用上述實用性的方法了,而是通過封裝相關隊列函數去描述這種結構。這是寫數據結構的一種大緻方法。
1.結構體定義與隊列的創建過程:
結構體定義:描述隊列的屬性:隊頭标記,隊尾标記,隊列空間
創建隊列其實就是創建結構體變量
具體代碼
ps:隊頭和隊尾頂标記初始值一般都是-1 ,為了滿足隊列标記和數組下标一緻
2.入隊操作
注意: 我們的實現是将最新的元素放在了數組的末尾, 那麼數組末尾的元素就是我們的隊列隊尾元素,故可以使用隊尾标記去計算隊列中的元素個數。然後每次入隊後,隊尾标記往後移動。
具體實現代碼:
3.出隊操作和獲取隊頭元素
注意: 出隊操作應該是将隊頭元素删除,由于數組實現的隊列無法删除,故隻能把隊頭标記往隊尾移動,簡稱為一種"僞删除"。
具體實現代碼:
4.判斷棧是否為空
用戶判斷棧中是否有元素,通過隊尾和隊頭标記去做即可
具體實現代碼:
動态申請内存的數組描述隊列測試代碼
ps:循環隊列是通過區域形成的循環,這裡不過多介紹,有興趣的可以看看相關資料。
鍊式隊列鍊式隊列: 鍊表的尾插法即可
具體實現源碼線上
#include <stdio.h>
#include <stdlib.h>
typedef struct
{
int data;
struct Node* next;
}NODE,*LPNODE;
LPNODE createNode(int data)
{
LPNODE newNode = (LPNODE)malloc(sizeof(NODE));
newNode->data = data;
newNode->next = NULL;
return newNode;
}
typedef struct
{
int queueSize;
LPNODE frontNode;
LPNODE tailNode;
}QUEUE,*LPQUEUE;
LPQUEUE createQueue()
{
LPQUEUE queue = (LPQUEUE)malloc(sizeof(QUEUE));
queue->queueSize = 0;
queue->frontNode = NULL;
queue->tailNode = NULL;
return queue;
}
void push(LPQUEUE queue, int data)
{
//無頭表頭鍊表的在封裝法
LPNODE newNode = createNode(data);
if (queue->queueSize == 0)
{
queue->frontNode = newNode;
queue->tailNode = newNode;
}
else
{
//無表頭鍊表的表尾插入
queue->tailNode->next = newNode;
queue->tailNode = newNode;
}
queue->queueSize ;
}
//FILO FIFO
void pop(LPQUEUE queue)
{
if (queue->queueSize != 0)
{
LPNODE nextNode = queue->frontNode->next;
free(queue->frontNode);
queue->frontNode = nextNode;
queue->queueSize--;
}
}
int front(LPQUEUE queue)
{
return queue->frontNode->data;
}
int empty(LPQUEUE queue)
{
return queue->queueSize==0;
}
int size(LPQUEUE queue)
{
return queue->queueSize;
}
int main()
{
LPQUEUE queue = createQueue();
for (int i = 1; i <= 3; i )
{
push(queue, i);
}
while (!empty(queue))
{
printf("%d\t", front(queue));
pop(queue);
}
printf("\n");
system("pause");
return 0;
}
優先隊列:根據優先權去決定你出隊的元素,故數據中存在優先權衡量的值,相關實現代碼如下:
#include <iostream>
#define MaxQueueSize 100 //隊列的大小
//數據類型 數據本身 優先權
typedef int ElementType; //定義數據類型地 别名
//數據 結構體
typedef struct
{
int priority; //優先權---工作量
ElementType element;//隊列中的元素
}DataType;
//隊列的結構體
typedef struct
{
int size;
//結構體的嵌套
DataType Queue[MaxQueueSize];
}PriQueue;
//讀取文件作業---調度讀取
//隊列操作
//初始化---初始化基本成員
//size Queue
void InitQueue(PriQueue *Q)
{
Q->size = 0;
}
//判斷隊列是否為空 NULL
//和它的初始化比較
int QueueEmpty(PriQueue *Q)
{
// -> 指向運算符 C:結構體指針 C : 類和結構體
// :: 作用域限定符
if (Q->size <= 0)
return 0; //标志
else
return 1; //不為空
// return 0 函數結束
}
//入隊 文件操作
int Push(PriQueue *Q, DataType data)
{
//入隊前判斷是否滿
if (Q->size >= MaxQueueSize)
{
std::cout << "杯子已滿,無法再倒水" << std::endl;
return 0;
}
else
{
//Q->size=0;
Q->Queue[Q->size] = data;
//入隊了隊列長度就要增長
Q->size ;
return 1;
}
}
//出隊
int Pop(PriQueue *Q, DataType *A)
{
DataType min; //最小的開始,排序
int minIndex = 0;
//短作業優先法
//喝水,先判斷杯子有沒有水
if (Q->size <= 0)
{
std::cout << "為空,無法出隊" << std::endl;
return 0;
}
else
{
//假設第一個作業是最短的
min = Q->Queue[0]; //1
for (int i = 1; i < Q->size; i )
{
//多了一個數據項 按照權值排序
//0
if (Q->Queue[i].priority < min.priority)
{
min = Q->Queue[i];
minIndex = i; //出隊依據就是最小作業序号
}
}
*A = Q->Queue[minIndex];
//難點
//删除完數組後,後面的元素往前移動
for (int i = minIndex 1; i < Q->size; i )
{
Q->Queue[i - 1] = Q->Queue[i];
minIndex = i;
}
Q->size--;
return 1;
}
}
//獲取隊頭元素
int GetQueue(PriQueue *Q, DataType *A)
{
DataType min; //最小的開始,排序
int minIndex = 0;
//短作業優先法
//喝水,先判斷杯子有沒有水
if (Q->size <= 0)
{
std::cout << "為空,無法出隊" << std::endl;
return 0;
}
else
{
//假設第一個作業是最短的
min = Q->Queue[0]; //1
for (int i = 1; i < Q->size; i )
{
//多了一個數據項 按照權值排序
//0
if (Q->Queue[i].priority < min.priority)
{
min = Q->Queue[i];
minIndex = i; //出隊依據就是最小作業序号
}
}
*A = Q->Queue[minIndex];
return 1;
}
}
希望對大家有幫助!
另外如果你想更好的提升你的編程能力,學好C語言C 編程!彎道超車,快人一步!
編程學習軟件分享:
編程學習視頻分享:
分享(源碼、項目實戰視頻、項目筆記,基礎入門教程)
歡迎轉行和學習編程的夥伴,利用更多的資料學習成長比自己琢磨更快哦!
C語言C 編程學習交流圈子,點擊下方【了解更多】獲取更多學習資料哦~
,更多精彩资讯请关注tft每日頭條,我们将持续为您更新最新资讯!