以連結串列為基礎實現鏈式佇列
/********************************************************************************
*
* file name: Linked_Queues
* author : yxw18679428019@163.com
* date : 2024/04/26
* function : 以連結串列為基礎實現鏈式佇列,一般把連結串列頭部作為隊頭,可以實現頭刪,
* 把連結串列尾部作為隊尾,可以實現尾插。
*
* note : None
* CopyRight (c) 2023-2024 yxw18679428019@163.com All Right Reseverd
* ****************************************************************************/
#include <stdio.h>
#include <stdlib.h>
#include <stdbool.h>
// 指的是順序棧中的元素的資料型別,使用者可以根據需要進行修改
typedef int DataType_t;
// 構造連結串列的結點,連結串列中所有結點的資料型別應該是相同的
typedef struct Linked_Queues
{
struct Linked_Queues *next; // 建立一個指標域
DataType_t data; // 建立資料域
} LinkQueu_t;
/*******************************************************************************
* name : LinkQueu_Create
* function : 建立一個空鏈式對列,空連結串列應該有一個頭結點,對連結串列進行初始化
* argument : None
*
*
* retval : 返回管理順序棧的地址
* author : yxw18679428019@163.com
* date : 2024/04/26
* note : None
* ***************************************************************************/
LinkQueu_t *LinkQueu_Create(void)
{
// 建立一個頭結點並對頭結點申請堆記憶體
LinkQueu_t *Head = (LinkQueu_t *)calloc(1, sizeof(LinkQueu_t));
// 判斷申請的堆記憶體是否成功如果失敗直接結束程式
if (NULL == Head)
{
perror("calloc memroy for Head is failed \n");
exit(-1);
}
// 2.對頭結點進行初始化,頭結點是不儲存有效內容的!!!
Head->next = NULL;
// 返回頭結點的地址
return Head;
}
/*******************************************************************************
* name : LinkQueu_NewNode
* function : 建立一個新的結點並對資料域與指標域進行初始化
* argument :
* @Data :傳入的資料值
*
* retval : 返回管理順序棧的地址
* author : yxw18679428019@163.com
* date : 2024/04/26
* note : None
* ***************************************************************************/
LinkQueu_t *LinkQueu_NewNode(DataType_t Data)
{
// 建立一個新結點並申請堆記憶體
LinkQueu_t *New = (LinkQueu_t *)calloc(1, sizeof(LinkQueu_t));
// 判斷堆記憶體是否申請成功如果申請失敗則直接退出程式
if (NULL == New)
{
perror("calloc memroy for NewNode is failed \n");
exit(-1);
}
// 對新結點的資料域與指標域進行初始化
New->next = NULL;
New->data = Data;
// 返回新結點的地址
return New;
}
/*******************************************************************************
* name : LinkQueu_Front
* function : 鏈式佇列的入列
* argument :
* @Head :頭結點的地址
* @Data :傳入的資料值
* retval : true and false
* author : yxw18679428019@163.com
* date : 2024/04/26
* note : None
* ***************************************************************************/
bool LinkQueu_Rear(LinkQueu_t *Head, DataType_t Data)
{
LinkQueu_t *Phead = Head; // 定義一個指標記錄頭結點
// 建立一個新的結點,
LinkQueu_t *New = LinkQueu_NewNode(Data);
if (NULL == New)
{
printf("can not insert new node\n");
return false;
}
// 判斷鏈式佇列是否為空
if (NULL == Head->next)
{
Head->next = New; // 如果為空則頭結點的next指標指向新結點
return true;
}
// 遍歷到尾結點
while (Phead->next)
{
Phead = Phead->next;
}
// 鏈式佇列為非空
Phead->next = New; // 尾結點的next指標指向新結點
return true;
}
/*******************************************************************************
* name : LinkQueu_Rear
* function : 鏈式佇列的出列
* argument :
* @Head :頭結點的地址
*
* retval : 返回刪除結點資料域的值
* author : yxw18679428019@163.com
* date : 2024/04/26
* note : None
* ***************************************************************************/
DataType_t LinkQueu_Front(LinkQueu_t *Head)
{
LinkQueu_t *Phead = Head->next; // 定義一個指標記錄首結點
DataType_t temp; // 備份首結點資料域的值
// 判斷鏈式佇列是否為空
if (Head->next == NULL)
{
printf("Linked Queues is empty \n");
return 0;
}
else
{
// 鏈式佇列不為空
if (Phead->next)
{
Head->next = Phead->next; // 頭結點的next指標指向首結點的直接後繼
Phead->next = NULL; //// 首結點的next指標指向NULL
temp = Phead->data;
free(Phead); // 釋放首結點的記憶體
}
else
{
Head->next = NULL;
free(Phead);
}
}
// 返回刪除結點的值
return temp;
}
/*******************************************************************************
* name : LinkQueu_Rear
* function : 遍歷結點,並輸出結點的資料域的值
* argument :
* @Head :頭結點的地址
*
* retval : None
* author : yxw18679428019@163.com
* date : 2024/04/26
* note : None
* ***************************************************************************/
void LinkQueu_Print(LinkQueu_t *Head)
{
LinkQueu_t *Phead = Head; // 備份頭結點
while (Phead->next)
{
Phead = Phead->next;
printf("%d\n", Phead->data);
}
}
int main(void)
{
LinkQueu_t *Head = LinkQueu_Create();
LinkQueu_Rear(Head, 1);
LinkQueu_Rear(Head, 2);
LinkQueu_Rear(Head, 3);
LinkQueu_Print(Head);
LinkQueu_Front(Head);
LinkQueu_Front(Head);
LinkQueu_Front(Head);
LinkQueu_Front(Head);
LinkQueu_Rear(Head, 3);
LinkQueu_Print(Head);
return 0;
}