c語言——棧(鏈表實現)
棧的鏈式存儲
鏈表部分
頭文件LinkList.h
#pragma once
#include<stdlib.h>
#include<string.h>
#include<stdio.h>
#ifdef __cplusplus
extern "C"{
#endif
typedef void * LinkList;
typedef void(*FOREACH)(void *);
typedef int(*COMPARE)(void *,void *);
//初始化鏈表
LinkList Init_LinkList();
//插入節點
void Insert_LinkList(LinkList list,int pos,void *data);
//遍歷鏈表
void Foreach_LinkList(LinkList list, FOREACH myforeach);
//按位置刪除
void RemoveByPos_LinkList(LinkList list,int pos);
//按值刪除
void RemoveByVal_LinkList(LinkList list, void *data, COMPARE compare);
//清空鏈表
void Clear_LinkList(LinkList list);
//大小
int Size_LinkList(LinkList list);
//銷燬鏈表
void Destroy_LinkList(LinkList list);
#ifdef __cplusplus
}
#endif
LinkList.c
#include"LinkList.h"
//鏈表節點數據類型
struct LinkNode
{
void *data;
struct LinkNode *next;
};
//鏈表數據類型
struct LList
{
struct LinkNode header;
int size;
};
//初始化鏈表
LinkList Init_LinkList()
{
struct LList *list = malloc(sizeof(struct LList));
if (NULL == list)
{
return NULL;
}
list->header.data = NULL;
list->header.next = NULL;
list->size = 0;
return list;
}
//插入節點
void Insert_LinkList(LinkList list, int pos, void *data)
{
if (NULL == list)
{
return;
}
if (NULL == data)
{
return;
}
struct LList * mylist = (struct LList *)list;
if (pos < 0 || pos > mylist->size)
{
pos = mylist->size;
}
//查找插入位置
struct LinkNode *pCurrent = &(mylist->header);
for (int i = 0; i < pos; ++i)
{
pCurrent = pCurrent->next;
}
//創建新節點
struct LinkNode *newnode = malloc(sizeof(struct LinkNode));
newnode->data = data;
newnode->next = NULL;
//新節點插入到鏈表中
newnode->next = pCurrent->next;
pCurrent->next = newnode;
mylist->size++;
}
//遍歷鏈表
void Foreach_LinkList(LinkList list, FOREACH myforeach) /*回調函數*/
{
if (NULL == list)
{
return;
}
if (NULL == myforeach)
{
return;
}
struct LList * mylist = (struct LList *)list;
struct LinkNode *pCurrent = mylist->header.next;
while (pCurrent != NULL)
{
myforeach(pCurrent->data);
pCurrent = pCurrent->next;
}
}
//按位置刪除
void RemoveByPos_LinkList(LinkList list, int pos)
{
if (NULL == list)
{
return;
}
struct LList *mylist = (struct LList *)list;
if (pos < 0 || pos > mylist->size - 1)
{
return;
}
//找位置
struct LinkNode *pCurrent = &(mylist->header);
for (int i = 0; i < pos; ++i)
{
pCurrent = pCurrent->next;
}
//先保存待刪除結點
struct LinkNode *pDel = pCurrent->next;
//重新建立待刪除結點的前驅和後繼結點關係
pCurrent->next = pDel->next;
//釋放刪除節點內存
free(pDel);
pDel = NULL;
mylist->size--;
}
//按值刪除
void RemoveByVal_LinkList(LinkList list, void *data, COMPARE compare)
{
if (NULL == list)
{
return;
}
if (NULL == data)
{
return;
}
if (NULL == compare)
{
return;
}
struct LList *mylist = (struct LList *)list;
//輔助指針變量
struct LinkNode *pPrev = &(mylist->header);
struct LinkNode *pCurrent = pPrev->next;
while (pCurrent != NULL)
{
if (compare(pCurrent->data, data))
{
//找到了
pPrev->next = pCurrent->next;
//釋放刪除節點內存
free(pCurrent);
pCurrent = NULL;
mylist->size--;
break;
}
pPrev = pCurrent;
pCurrent = pCurrent->next;
}
}
//清空鏈表
void Clear_LinkList(LinkList list)
{
if (NULL == list)
{
return;
}
struct LList *mylist = (struct LList *)list;
//輔助指針變量
struct LinkNode *pCurrent = mylist->header.next;
while (pCurrent != NULL)
{
//先緩存下一個節點的地址
struct LinkNode *pNext = pCurrent->next;
//釋放當前結點內存
free(pCurrent);
pCurrent = pNext;
}
mylist->header.next = NULL;
mylist->size = 0;
}
//大小
int Size_LinkList(LinkList list)
{
if (NULL == list)
{
return -1;
}
struct LList *mylist = (struct LList *)list;
return mylist->size;
}
//銷燬鏈表
void Destroy_LinkList(LinkList list)
{
if (NULL == list)
{
return;
}
//清空鏈表
Clear_LinkList(list);
free(list);
list = NULL;
}
棧部分
頭文件LinkStack.h
#pragma once
#include<stdlib.h>
#include"LinkList.h"
struct StackNode
{
struct StackNode *next;
};
struct LStack
{
struct StackNode header; //頭結點
int size;
};
typedef void* LinkStack;
#ifdef __cplusplus
extern "C"{
#endif
//初始化
LinkStack Init_LinkStack();
//入棧
void Push_LinkStack(LinkStack stack, void *data);
//出棧
void Pop_LinkStack(LinkStack stack);
//獲得棧頂元素
void* Top_LinkStack(LinkStack stack);
//獲得大小
int Size_LinkStack(LinkStack stack);
//銷燬棧
void Destroy_LinkStack(LinkStack stack);
#ifdef __cplusplus
}
#endif
LinkStack.c
#include"LinkStack.h"
//初始化
LinkStack Init_LinkStack()
{
struct LStack *stack = malloc(sizeof(struct LStack));
if (NULL == stack)
{
return NULL;
}
stack->header.next = NULL;
stack->size = 0;
return stack;
}
//入棧
void Push_LinkStack(LinkStack stack, void *data)
{
if (NULL == stack)
{
return;
}
if (NULL == data)
{
return;
}
struct LStack *ls = (struct LStack *)stack;
struct StackNode *node = (struct StackNode *)data;
node->next = ls->header.next;
ls->header.next = node;
++(ls->size);
}
//出棧
void Pop_LinkStack(LinkStack stack)
{
if (NULL == stack)
{
return;
}
struct LStack *ls = (struct LStack *)stack;
if (ls->size == 0)
{
return;
}
//緩存下第一個節點
struct StackNode *pFirst = ls->header.next;
ls->header.next = pFirst->next;
ls->size--;
}
//獲得棧頂元素
void* Top_LinkStack(LinkStack stack)
{
if (NULL == stack)
{
return NULL;
}
struct LStack *ls = (struct LStack *)stack;
if (ls->size == 0)
{
return NULL;
}
return ls->header.next;
}
//獲得大小
int Size_LinkStack(LinkStack stack)
{
if (NULL == stack)
{
return -1;
}
struct LStack *ls = (struct LStack *)stack;
return ls->size;
}
//銷燬棧
void Destroy_LinkStack(LinkStack stack)
{
if (NULL == stack)
{
return;
}
free(stack);
stack = NULL;
}
測試——棧的鏈式存儲
#define _CRT_SECURE_NO_WARNINGS
#include<stdio.h>
#include<string.h>
#include<stdlib.h>
#include"LinkStack.h"
struct Person
{
struct StackNode node;
char name[64];
int age;
};
void test()
{
//初始化棧
LinkStack stack = Init_LinkStack();
//創建數據
struct Person p1 = { NULL, "aaa", 10 };
struct Person p2 = { NULL, "bbb", 20 };
struct Person p3 = { NULL, "ccc", 30 };
struct Person p4 = { NULL, "ddd", 40 };
struct Person p5 = { NULL, "eee", 50 };
struct Person p6 = { NULL, "fff", 60 };
//數據入棧
Push_LinkStack(stack, &p1);
Push_LinkStack(stack, &p2);
Push_LinkStack(stack, &p3);
Push_LinkStack(stack, &p4);
Push_LinkStack(stack, &p5);
Push_LinkStack(stack, &p6);
//輸出棧中所有元素
while (Size_LinkStack(stack) > 0)
{
//獲得棧頂元素
struct Person *person = (struct Person *)Top_LinkStack(stack);
//打印
printf("Name:%s Age:%d\n", person->name, person->age);
//彈出棧頂元素
Pop_LinkStack(stack);
}
printf("Size:%d\n", Size_LinkStack(stack));
}
int main(){
test();
system("pause");
return EXIT_SUCCESS;
}
運行
Name:fff Age:60
Name:eee Age:50
Name:ddd Age:40
Name:ccc Age:30
Name:bbb Age:20
Name:aaa Age:10
Size:0