以連結串列作為基礎實現棧空間(鏈式棧)
/********************************************************************************
*
* file name: LinkedStack.c
* author : yxw18679428019@163.com
* date : 2024/04/25
* function : 實現鏈式棧的入棧(Push)與出棧(Pop)
* note : None
*
* CopyRight (c) 2023-2024 yxw18679428019@163.com All Right Reseverd
* ****************************************************************************/
#include <stdio.h>
#include <stdbool.h>
#include <stdlib.h>
// 鏈棧中的元素的資料型別,使用者可以根據需求進行修改
typedef int DataType_t;
// 構建記錄鏈棧LinkedStack的各項引數(棧底地址,棧容量,棧頂元素的小標)的結構體
typedef struct LinkedStack
{
struct LinkedStack *next;
DataType_t data;
} LinkStack_t;
/************************************************************************
* name : LinkStack_Dreate
* function : 建立一個空的鏈棧,並對資料域與指標域進行初始化
* argument : None
*
*
* retval : 返回頭結點的地址
* author : yxw18679428019@163.com
* date : 2024/04/25
* note : None
* *********************************************************************/
LinkStack_t *LinkStack_Create(void)
{
// 建立一個頭結點並對頭結點申請記憶體
LinkStack_t *Head = (LinkStack_t *)calloc(1, sizeof(LinkStack_t));
// 判斷申請堆記憶體是否成功
if (NULL == Head)
{
perror("calloc memroy from Head is failed");
exit(-1);
}
// 進行初始化
Head->next = NULL;
return Head;
}
/************************************************************************
* name : LinkStack_NewNode
* function : 建立一個新的結點並對資料域與指標域進行初始化
* argument :
* @Data :入棧的資料
*
* retval : 返回新結點的地址
* author : yxw18679428019@163.com
* date : 2024/04/25
* note : None
* *********************************************************************/
LinkStack_t *LinkStack_NewNode(DataType_t Data)
{
// 1.建立一個新結點並對新結點申請記憶體
LinkStack_t *New = (LinkStack_t *)calloc(1, sizeof(LinkStack_t));
if (NULL == New)
{
perror("Calloc memory for NewNode is Failed");
return NULL;
}
// 對新結點的指標域與資料域進行初始化
New->data = Data;
New->next = NULL;
return New;
}
/************************************************************************
* name : LinkStack_Push
* function : 入棧
* argument :
* @Head :頭結點的地址
* @Data :入棧的資料
* retval : true and false
* author : yxw18679428019@163.com
* date : 2024/04/25
* note : None
* *********************************************************************/
bool LinkStack_Push(LinkStack_t *Head, DataType_t Data)
{
// 建立一個新的結點
LinkStack_t *New = LinkStack_NewNode(Data);
if (NULL == New)
{
printf("can not insert new node!\n");
return false;
}
// 如果鏈棧為空
if (NULL == Head->next)
{
// 頭結點的next指標指向新結點
Head->next = New;
return true;
}
// 鏈棧為非空
New->next = Head->next; // 新結點的next指標指向首結點
Head->next = New; // 頭結點的next指標指向新結點
return true;
}
/************************************************************************
* name : LinkStack_Pop
* function : 出棧
* argument :
* @Head :頭結點的地址
*
* retval : true and false
* author : yxw18679428019@163.com
* date : 2024/04/25
* note : None
* *********************************************************************/
bool LinkStack_Pop(LinkStack_t *Head)
{
LinkStack_t *Phead = Head->next; // 備份首結點
// 判斷鏈棧是否為空
if (NULL == Head->next)
{
printf("Linked Stack is empty!\n");
return false;
}
// 鏈棧不為空
if (NULL == Phead->next) // 鏈棧中只有一個首結點
{
Head->next = NULL; // 頭結點的next指標指向NULL
free(Phead); // 釋放首結點記憶體
}
else
{
Head->next = Phead->next; // 頭結點指向待刪除結點的直接後繼
Phead->next = NULL; // 待刪除結點的next指標指向NULL
free(Phead); // 釋放刪除結點的記憶體
}
}
/************************************************************************
* name : LinkStack_Print
* function : 遍歷鏈式棧的每個結點並輸出每個結點的資料與的值
* argument :
* @Head :頭結點的地址
*
* retval : true and false
* author : yxw18679428019@163.com
* date : 2024/04/25
* note : None
* *********************************************************************/
bool LinkStack_Print(LinkStack_t *Head)
{
// 對單向迴圈連結串列的頭結點的地址進行備份
LinkStack_t *Phead = Head;
// 判斷當前連結串列是否為空,為空則直接退出
if (NULL == Head->next)
{
printf("current linked stack is empty!\n");
return false;
}
// 從首結點開始遍歷
while (Phead->next)
{
// 把頭結點的直接後繼作為新的頭結點
Phead = Phead->next;
// 輸出頭結點的直接後繼的資料域
printf("data = %d\n", Phead->data);
// 判斷是否到達尾結點,尾結點的next指標是指向首結點的地址
if (Phead->next == NULL)
{
break;
}
}
return true;
}
int main(void)
{
LinkStack_t *Head = LinkStack_Create();
LinkStack_Push(Head, 1);
LinkStack_Push(Head, 2);
LinkStack_Push(Head, 3);
LinkStack_Print(Head);
LinkStack_Pop(Head);
LinkStack_Pop(Head);
LinkStack_Pop(Head);
LinkStack_Pop(Head);
LinkStack_Print(Head);
LinkStack_Push(Head, 1);
LinkStack_Print(Head);
}