单向链表
slist.h
#ifndef __SLIST_H
#define __SLIST_H
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <stdbool.h>
// 定义单链表结构
typedef int DATA;
typedef struct Node
{
DATA data; // 存储数据---数据域
struct Node *next; // 存储下一个节点的地址---指针域
} NODE;
// 链表创建
int slist_create(NODE**,DATA);】.
// 向链表头部插入一个节点数据(头插法)
int slist_addHead(NODE**,DATA);
// 向链表尾部插入一个节点数据(尾插法)
int slist_addTail(NODE**,DATA);
// 向链表中间插入一个节点数据(中间插法)
int slist_insert(NODE**,DATA,DATA);
// 遍历链表数据
void slist_showAll(const NODE* head);
// 回收链表
void slist_destroy(NODE** head);
// 链表数据查询
NODE* slist_find(const NODE *head,DATA data);
// 更新链表数据
int slist_update(const NODE *head,DATA old_data,DATA new_data);
// 删除链表数据(剔除节点,不是真正意义上的删除)
int slist_delete(NODE**,DATA);
#endif
slist.c
#include "slist.h"
/*
@function: int slist_create(NODE** head,DATA data);
@berif: 创建单项链表
@argument: head: 指向头指针变量的地址,用来接收首节点地址
data: 存储在节点中的数据
@return : 成功返回 0
失败返回 -1
*/
int slist_create(NODE **head, DATA data)
{
// 申请内存
NODE *p = (NODE *)malloc(sizeof(NODE));
// 校验
if (!p)
{
return -1;
}
// 赋值操作
p->data = data;
p->next = NULL;
*head = p;
return 0;
}
/*
@function: int slist_addHead(NODE** head,DATA data);
@berif: 向链表头部插入一个节点数据(头插法)
@argument: head: 指向头指针变量的地址,用来接收首节点地址
data: 存储在新节点中的数据
@return : 成功返回 0
失败返回 -1
*/
int slist_addHead(NODE **head, DATA data)
{
// 创建一个新节点(申请内存)
NODE *p = (NODE *)malloc(sizeof(NODE));
// 校验
if (!p)
{
return -1;
}
// 给节点添加新数据(创建节点的目的是存储数据)
p->data = data;
// 新节点指向原本的head节点
p->next = *head;
// 我们要让p作为我们新的head
*head = p;
return 0;
}
/*
@function: int slist_addTail(NODE** head,DATA data);
@berif: 向链表尾部插入一个节点数据(尾插法)
@argument: head: 指向头指针变量的地址,用来接收首节点地址
data: 存储在新节点中的数据
@return : 成功返回 0
失败返回 -1
*/
int slist_addTail(NODE **head, DATA data)
{
// 创建一个新节点(申请内存)
NODE *pNew = (NODE *)malloc(sizeof(NODE));
// 校验
if (!pNew)
{
return -1;
}
// 赋值操作
pNew->data = data; // 存数据
pNew->next = NULL; // 因为是最后一个节点,所有没有指向
// 获取尾部节点,默认head头结点就是尾结点,p用来保存真实的尾结点
NODE *p = *head, *q = NULL;
if (!p)
{
// 如果说头节点不存在,我们直接将新节点作为头结点,一般不会发生
*head = pNew;
return 0;
}
// 通过一个循环,找尾结点
while (p)
{
// 为什么要定义q,因为p是在变化的
q = p;
p = p->next;// 指针向下指
}
// 让原本的尾结点指向新插入的的节点,此时新插入的节点变成了尾结点
q->next = pNew;
return 0;
}
/*
@function: int slist_insert(NODE** head,DATA pos ,DATA data);
@berif: 向链表节点值为pos的位置插入一个节点数据data
@argument: head: 指向头指针变量的地址
pos: 插入节点位置的节点数据
data: 存储在新节点中的数据
@return : 成功返回 0
失败返回 -1
*/
int slist_insert(NODE** head,DATA pos,DATA data)
{
// 创建一个新节点,并申请内存
NODE *pNew = (NODE*)malloc(sizeof(NODE));
if(!pNew)
{
perror("内存申请失败!");
return -1;
}
// 给新节点赋初值
pNew->data = data;
pNew->next = NULL;
// 声明变量,p是pos对应位置的节点,默认是头结点,q是pos对应节点的上一个节点
NODE *p = *head,*q = NULL;
// 第一种情况:头结点不存在
if(!p)
{
// 新节点pNew作为头结点
*head = pNew;
return 0;
}
// 第二种情况:只有头结点
if(memcmp(&(p->data),&pos,sizeof(DATA)) == 0)
{
// 头插法
// 新节点的next指向head节点
pNew->next = *head;
// 改变指向,将pNew作为新的头结点
*head = pNew;
return 0;
}
// 第三种情况:既有头结点,也有普通节点
while (p)
{
// 找pos对应位置的节点
if(memcmp(&(p->data),&pos,sizeof(DATA)) == 0)
{
// pNew在p前
pNew->next = p;
// pNew在q后
q->next = pNew;
return 0;
}
q = p;// q在p的前一位,一前(q)一后(p)
p = p ->next;
}
// 尾插法
q->next = pNew;
return 0;
}
/*
@function: NODE* slist_find(const NODE* head,DATA data);
@berif: 查找链表数据data
@argument: head: 指向头指针变量
data: 待查找的数据
@return : 成功返回节点的地址
失败返回NULL
*/
NODE* slist_find(const NODE *head,DATA data)
{
// 创建一个变量,用来接收链表
const NODE* p = head;
while(p)
{
if(memcmp(&(p->data),&data,sizeof(DATA))==0)
{
return (NODE*)p;
}
// 移动节点
p = p->next;
}
return NULL;
}
/*
@function: int slist_update(const NODE* head,DATA old_data,DATA new_data);
@berif: 更新链表数据old_data 为 new_data
@argument: head: 指向头指针变量
old_data: 待更新的节点数据
new_data: 更新后的节点数据
@return : 成功返回 0
失败返回 -1
*/
int slist_update(const NODE* head,DATA old_data,DATA new_data)
{
NODE* p = NULL;
if(!(p = slist_find(head,old_data)))
{
return -1;
}
p->data = new_data;
return 0;
}
/*
@function: void slist_showAll(const NODE* head);
@berif: 遍历链表数据
@argument: head: 指向头指针变量
@return : 无
*/
void slist_showAll(const NODE* head)
{
// 创建一个变量用来接收链表
const NODE* p = head;
// 遍历链表
while (p)
{
printf("%d ",p->data);
p = p->next;
}
printf("\n");
}
/*
@function: int slist_delete(NODE** head,DATA data);
@berif: 删除链表中节点值为data的节点
@argument: head: 指向头指针变量的地址
data: 删除节点中的数据
@return : 成功返回 0
失败返回 -1
*/
int slist_delete(NODE** head,DATA data)
{
// 指针尾随
NODE *p = *head,*q = NULL;
// 第一种情况:头结点不存在(链表本身不存在),无法操作
if(!p)
{
return -1;
}
// 第二种情况:只有一个节点
if(memcmp(&(p->data),&data,sizeof(DATA)) == 0)
{
*head = p -> next;
free(p);
return 0;
}
// 第三种情况:有多个节点
while (p)
{
if(memcmp(&(p->data),&data,sizeof(DATA)) == 0)
{
q->next = p->next;// p的上一个节点的next指向p的下一个节点
// 这个回收不会影响到链表的删除
free(p);
return 0;
}
q = p;
p = p->next;// p->next代表的是p的下一个节点,将p的下一个节点赋值给p,相当于p移动了一位
}
return -1;
}
/*
@function: void slist_destroy(NODE** head);
@berif: 回收链表
@argument: head: 指向头指针变量的地址
@return : 无
*/
void slist_destroy(NODE** head)
{
// 指针尾随
NODE *p = *head,*q = NULL;
while(p)
{
q = p;// 12
p = p->next;// 13
// 回收前一个节点
free(q);
}
*head = NULL;
}
Slist_main.c
#include "slist.h"
#define DELETE 1
int main()
{
NODE *head = NULL;
if (slist_create(&head, 888) < 0)
{
perror("单链表创建失败!");
// exit(0);
return -1;
}
printf("单链表创建成功!\n");
slist_addTail(&head, 999);
slist_addTail(&head, 222);
slist_addTail(&head, 666);
slist_addTail(&head, 777);
// 运行效果:999 222 666 777
slist_addHead(&head, 555);
// 运行效果:555 999 222 666 777
slist_insert(&head, 555, 1024);
// 运行效果:1024 555 999 222 666 777
slist_insert(&head, 222, 1080);
// 运行效果:1024 555 999 1080 222 666 777
slist_showAll(head);
DATA data;
while (1)
{
#ifdef DELETE
printf("请输入要删除的数据:");
scanf("%d", &data);
if (data == -1)
break;
if (slist_delete(&head, data) < 0)
{
puts("删除失败,请重试");
continue;
}
slist_showAll(head);
#else
NODE *pFind = NULL;
DATA newdata = 512;
printf("请输入要查找的数据:");
scanf("%d", &data);
if (data == -1)
break;
// if(!(pFind = slist_find(head,data)))
if (slist_update(head, data, newdata) == -1)
{
puts("查找的数据不存在,请重试");
continue;
}
// printf("查找数据:%d 内存地址:%p\n",pFind -> data, &(pFind -> data));
slist_showAll(head);
#endif
}
slist_destroy(&head);
puts("====销毁后====");
slist_showAll(head);
return 0;
}
双向链表
dlist.h
#ifndef __DLIST_H
#define __DLIST_H
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <stdbool.h>
// 定义链表节点中数据的类型,本次案例使用int类型
typedef int DATA;
// 定义节点
typedef struct node
{
DATA data; // 数据
struct node *prev; // 前驱指针
struct node *next; // 后继指针
}NODE;
// 创建链表(初始化)
int dlist_create(NODE**,DATA);
// 向链表头部插入数据(头插法)
int dlist_addHead(NODE**,DATA);
// 向链表尾部插入数据(尾插法)
int dlist_addTail(NODE**,DATA);
// 向链表任意位置插入数据(中间插法)
int dlist_insert(NODE**,DATA,DATA);
// 链表数据遍历
void dlist_showAll(const NODE*);
// 链表数据查询
NODE* dlist_find(const NODE*,DATA);
// 链表数据更新
int dlist_update(const NODE*,DATA,DATA);
// 链表数据删除
int dlist_delete(NODE**,DATA);
// 链表回收
void dlist_destroy(NODE**);
#endif
dlist.c
#include "dlist.h"
/**
* @function: int dlist_create(NODE**,DATA);
* @berif: 创建双向链表
* @argument: head: 指向头指针变量的地址,用来接收首节点地址
* data: 存储在节点中的数据
* @return : 成功返回 0
* 失败返回 -1
*/
int dlist_create(NODE **head, DATA data)
{
// 创建一个节点(申请内存)
NODE *pNew = (NODE *)malloc(sizeof(NODE));
if (!pNew)
{
perror("内存申请失败!");
return -1;
}
// 节点的初始化
pNew->data = data;
pNew->prev = pNew->next = NULL; // 给前驱指针和后继指针都赋值为NULL
// 将pNew作为头结点
*head = pNew;
return 0;
}
/**
* @function: int dlist_addHead(NODE**,DATA);
* @berif: 向链表头部插入数据
* @argument: head: 指向头指针变量的地址,用来接收首节点地址
* data: 存储在节点中的数据
* @return : 成功返回 0
* 失败返回 -1
*/
int dlist_addHead(NODE **head, DATA data)
{
// 创建一个节点,申请内存
NODE *pNew = (NODE *)malloc(sizeof(NODE));
// 校验
if (!pNew)
{
perror("内存申请失败!");
return -1;
}
// 给节点赋值
pNew->data = data;
pNew->prev = NULL;
pNew->next = *head;
// 如果头结点存在,需要设置head.prev指向pNew
if (*head)
{
(*head)->prev = pNew;
}
// 将pNew作为新的头结点
*head = pNew;
return 0;
}
/**
* @function: int dlist_addTail(NODE**,DATA);
* @berif: 向链表尾部插入数据
* @argument: head: 指向头指针变量的地址,用来接收首节点地址
* data: 存储在节点中的数据
* @return : 成功返回 0
* 失败返回 -1
*/
int dlist_addTail(NODE **head, DATA data)
{
// 创建一个节点,申请内存
NODE *pNew = (NODE *)malloc(sizeof(NODE));
if (!pNew)
{
perror("内存申请失败!");
return -1;
}
// 给节点赋初值
pNew->data = data;
pNew->prev = pNew->next = NULL;
// 定义一个变量,用来存储尾结点
NODE *p = *head;
// 第一种情况:没有节点,pNew作为头结点
if (!p)
{
*head = pNew;
return 0;
}
// 第二种情况:有节点,向末尾添加pNew
while (p->next)
{
// 移动p的位置
p = p->next;
}
// 末尾的p节点跟pNew建立联系,此时pNew称为尾结点
p->next = pNew;
pNew->prev = p;
return 0;
}
/**
* @function: int dlist_insert(NODE**,DATA,DATA);
* @berif: 向链表任意位置插入数据(中间插法)
* @argument: head: 指向头指针变量的地址,用来接收首节点地址
* pos:目标位置数据
* data: 存储在节点中的数据
* @return : 成功返回 0
* 失败返回 -1
*/
int dlist_insert(NODE **head, DATA pos, DATA data)
{
// 创建节点,申请内存
NODE *pNew = (NODE *)malloc(sizeof(NODE));
if (!pNew)
{
perror("内存申请失败!");
return -1;
}
// 给节点赋初值
pNew->data = data;
pNew->prev = pNew->next = NULL;
NODE *p = *head, *q = NULL;
// 第一种情况:没有节点,pNew作为头结点
if (!p)
{
*head = pNew;
return 0;
}
// 第二种情况:pos对应的节点刚好是头结点(有效节点是头结点,只有一个节点的时候)
if (memcmp(&(p->data), &pos, sizeof(DATA)) == 0)
{
pNew->next = p;
p->prev = pNew;
*head = pNew;
return 0;
}
// 第三种情况:pos对应的节点不是头结点(有效节点超过两个)
while (p) // p 判断当前节点是否为NULL,p->next 判断写一个节点是否为NULL
{
if (memcmp(&(p->data), &pos, sizeof(DATA)) == 0)
{
pNew->next = p;
pNew->prev = q;
p->prev = pNew;
q->next = pNew;
return 0;
}
// 记录当前位置(上一个节点的位置)
q = p;
// 记录下一个节点的位置,也就是更新后的p
p = p->next;
}
// 如果在链表中找不到pos对应的节点,就尾插
q->next = pNew;
pNew->prev = q;
return 0;
}
/**
* @function: void dlist_showAll(const NODE*);
* @berif: 向链表任意位置插入数据(中间插法)
* @argument: head: 指向头指针变量的地址,用来接收首节点地址
* pos:目标位置数据
* data: 存储在节点中的数据
* @return : 成功返回 0
* 失败返回 -1
*/
void dlist_showAll(const NODE *head)
{
const NODE *p = head;
while (p)
{
printf("%d ", p->data);
// 向后遍历
p = p->next;
// 向前遍历
// p = p->prev;
}
printf("\n");
}
/**
* @function: NODE* dlist_find(const NODE*,DATA);
* @berif: 链表数据查询(根据指定的数据查找节点)
* @argument: head: 指向头指针变量的地址,用来接收首节点地址
* data: 要检索的数据
* @return : 成功返回 NODE*
* 失败返回 NULL
*/
NODE *dlist_find(const NODE *head, DATA data)
{
// 创建一个变量去接收链表
const NODE *p = head;
while (p)
{
if (memcmp(&(p->data), &data, sizeof(DATA)) == 0)
{
return (NODE *)p;
}
p = p->next;
}
return NULL;
}
//
/**
* @function: dlist_update(const NODE*,DATA,DATA);
* @berif: 链表数据更新
* @argument: head: 指向头指针变量的地址,用来接收首节点地址
* old_data:源数据
* new_data: 目标数据
* @return : 成功返回 0
* 失败返回 -1
*/
int dlist_update(const NODE *head, DATA old_data, DATA new_data)
{
// 用来接收查询到的节点
NODE *pFind = NULL;
// 利用刚刚写的查询函数,查询
if (!(pFind = dlist_find(head, old_data)))
{
return -1;
}
// 更新数据
pFind->data = new_data;
return 0;
}
/**
* @function: dlist_delete(NODE**,DATA);
* @berif: 链表数据删除
* @argument: head: 指向头指针变量的地址,用来接收首节点地址
* data: 需要删除的数据
* @return : 成功返回 0
* 失败返回 -1
*/
int dlist_delete(NODE **head, DATA data)
{
// 记录需要删除的节点的位置
NODE *p = *head;
// 第一种情况:链表不存在
if (!p)
{
return -1;
}
// 第二种情况:删除的数据对应的节点正好是头结点
if (memcmp(&(p->data), &data, sizeof(DATA)) == 0)
{
// 1. 链表中只有一个节点
if (p->next == NULL)
{
free(p);
*head = NULL;
return 0;
}
// 2. 链表中有两个以上节点
// 执行下列代码之前,head和p都指向头结点,下面代码的意思是:将p节点的下一个节点作为新的头结点
*head = p->next;
// 解除p的引用关系(下一个节点指向它的关系)
p->next->prev = NULL;
// 回收p
free(p);
return 0;
}
// 正常删除:链表中要删除的节点不是头结点
while (p)
{
if (memcmp(&(p->data), &data, sizeof(DATA)) == 0)
{
// p的上一个节点的next指向p的下一个节点
p->prev->next = p->next;
// p是尾结点
if(p->next==NULL)
{
// 解除p的上一个节点跟p的引用
p->prev->next = NULL;
}
else // p不是尾结点
{
// p的下一个节点的prev指向p的上一个节点
p->next->prev = p->prev;
}
// 回收解除引用的节点
free(p);
return 0;
}
// 改变循环条件
p = p->next;
}
return -1;
}
/**
* @function: void dlist_destroy(NODE**);
* @berif: 链表回收
* @argument: head: 指向头指针变量的地址,用来接收首节点地址
* old_data:源数据
* new_data: 目标数据
* @return : 成功返回 0
* 失败返回 -1
*/
void dlist_destroy(NODE **head)
{
// p记录移动的节点,q记录需要回收的节点
NODE *p = *head, *q = NULL;
while (p)
{
// 实现指针尾随
q = p; // 前一个节点
p = p->next; // 后一个节点
// 回收q
free(q);
}
*head = NULL;
}
Dlist_main.c
#include "dlist.h"
#define OP 3
int main()
{
NODE *head = NULL;
// if (dlist_create(&head, 666) != -1)
// {
// printf("链表创建成功!\n");
// }
// else
// {
// printf("链表创建失败!\n");
// }
int a[] = {1, 3, 5, 7, 9};
int n = sizeof a / sizeof a[0];
register int i = 0;
for (; i < n; i++)
{
dlist_addTail(&head, a[i]);
}
dlist_addHead(&head, 888);
dlist_insert(&head, 5, 999);
dlist_showAll(head); // 888 1 3 999 5 7 9
while (1)
{
#if (OP == 0)
DATA data;
NODE *pFind = NULL;
printf("请输入要查找的数据(-1 退出):");
scanf("%d", &data);
if (data == -1)
break;
if (!(pFind = dlist_find(head, data)))
{
puts("查找的数据不存在,请重试...");
continue;
}
printf("在内存地址为 %p 的内存空间中找到了 %d\n", &(pFind->data), pFind->data);
#elif (OP == 1)
DATA data;
NODE *pFind = NULL;
printf("请输入要插入位置的数据(-1 退出):");
scanf("%d", &data);
if (data == -1)
break;
if (dlist_insert(&head, data, 407))
{
puts("插入失败,请重试...");
continue;
}
dlist_showAll(head);
#elif (OP == 2)
DATA data;
NODE *pFind = NULL;
printf("请输入要修改位置的数据(-1 退出):");
scanf("%d", &data);
if (data == -1)
break;
if (dlist_update(head, data, 407))
{
puts("修改失败,请重试...");
continue;
}
dlist_showAll(head);
#else
DATA data;
NODE *pFind = NULL;
printf("请输入要删除位置的数据(-1 退出):");
scanf("%d", &data);
if (data == -1)
break;
if (dlist_delete(&head, data))
{
puts("删除失败,请重试...");
continue;
}
dlist_showAll(head);
#endif
}
dlist_destroy(&head);
puts("=====回收后====");
dlist_showAll(head);
return 0;
}
顺序队列
squeue.h
#ifndef __SQUEUE_H
#define __SQUEUE_H
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
// 定义测试的数据类型
typedef int DATA;
// 创建顺序队列
typedef struct
{
DATA *pData; // 队列入口,也就是我们创建的堆数组,我们入队的所有数据存储在这里
int size; // 队列的总容量(堆数组的大小)
int head; // 队头元素下标
int tail; // 队尾元素下标
} SQueue;
// 初始化队列
int SQ_init(SQueue *q, int num);
// 判断队列是否已满
int SQ_isfull(SQueue *q);
// 判断队尾是否为空
int SQ_isempty(SQueue *q);
// 入队
int SQ_push(SQueue *s, DATA data);
// 出队
int SQ_pop(SQueue *st, DATA *data);
// 回收队列
int SQ_free(SQueue *st);
#endif
squeue.c
#include "squeue.h"
// 初始化队列
int SQ_init(SQueue *q, int num)
{
// 首先,给pData,也就是堆数组申请空间
q->pData = (DATA *)calloc(sizeof(DATA), num);
// 校验
if (q->pData == NULL)
{
perror("内存申请失败!");
return -1;
}
// 初始化
q->size = num;
// 默认头尾下标都是0,此时队列为空(当头和尾的下标相等时,队列是空的)
q->head = q->tail = 0;
return 0;
}
// 判断队列是否已满
int SQ_isfull(SQueue *q)
{
return (q->tail + 1) % q->size == q->head;
}
// 判断队尾是否为空
int SQ_isempty(SQueue *q)
{
return q->tail == q->head;
}
// 入队
int SQ_push(SQueue *s, DATA data)
{
// 判断队列是否已满
if (SQ_isfull(s))
{
return -1;
}
// 将数据存放到队尾
s->pData[s->tail] = data;
s->tail = (s->tail + 1) % s->size;
return 0;
}
// 出队
int SQ_pop(SQueue *st, DATA *data)
{
// 判断队列是否为空
if (SQ_isempty(st))
return -1;
*data = st->pData[st->head];
st->head = (st->head + 1) % st->size;
return 0;
}
// 回收队列
int SQ_free(SQueue *st)
{
if (st->pData)
{
free(st->pData);
st->pData = NULL;
}
st->head = st->tail = 0;
}
Squeue_main.c
#include "squeue.h"
#include <stdio.h>
int main(void)
{
SQueue queue;
SQ_init(&queue,10);
register int i = 1;
for(; i <= 10 ; i++)
SQ_push(&queue, i);
if( -1 == SQ_push(&queue,1024))
fprintf(stderr,"满队,入队失败!\n");
while(!SQ_isempty(&queue))
{
DATA data;
SQ_pop(&queue,&data);
printf("%4d",data);
}
printf("\n");
SQ_free(&queue);
return 0;
}
栈
sstack.h
#ifndef __SSTACK_H
#define __SSTACK_H
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
// 定义数据的类型,可以是复杂的结构体,本案例就使用int
// typedef struct Book
// {
// int id;
// char *name;
// int bookId;
// char *author;
// }DATA;
typedef int DATA;
// 顺序栈结构体
typedef struct
{
DATA *pData;// 栈中元素的地址[12,13,14]
int size;// 顺序栈的大小(数组的大小)
int top; // 栈顶元素下标
}SeqStack;
// 初始化栈
int SStack_init(SeqStack *s,int size);
// 判断栈是否已满
int SStack_isfull(SeqStack *s);
// 判断栈是否为空
int SStack_isempty(SeqStack *s);
// 入栈|压栈
int SStack_push(SeqStack *s,DATA data);
// 出栈|弹栈(弹出指定元素)
int SStack_pop(SeqStack *s,DATA *data);
// 出栈|弹栈(弹出所有元素)
// 回收栈
int SStack_destroy(SeqStack *s);
#endif
sstack.c
#include "sstack.h"
// 初始化栈
int SStack_init(SeqStack *s,int size)
{
// 给栈中的元素申请存储空间
s->pData = (DATA*)calloc(sizeof(DATA),size);
// 校验
if(s->pData == NULL)
{
perror("内存申请失败!");
return -1;
}
// 初始化
s->size = size;
s->top = -1;
return 0;
}
// 判断栈是否已满
int SStack_isfull(SeqStack *s)
{
return s->top + 1 == s->size;
}
// 判断栈是否为空
int SStack_isempty(SeqStack *s)
{
return s->top == -1;
}
// 入栈|压栈
int SStack_push(SeqStack *s,DATA data){
// 判断栈是否已满
if(SStack_isfull(s))
{
printf("顺序栈已填满!\n");
return -1;
}
// 操作栈
s->top++;// top向后偏移一位,top自增
s->pData[s->top] = data;// 在更新后的top位置插入数据
return 0;
}
// 出栈|弹栈(弹出指定元素)
int SStack_pop(SeqStack *s,DATA *data)
{
// 判断栈是否为空
if(SStack_isempty(s))
{
printf("顺序栈已为空!\n");
return -1;
}
// 将弹出的元素返回
*data = s->pData[s->top];
// 改变top
s->top--;
// printf("弹出数据:%d\n",*data);
return 0;
}
// 回收栈
int SStack_destroy(SeqStack *s){
if(s->pData)
{
// 释放内存
free(s->pData);
s->pData = NULL;
}
// 重置top
s->top = -1;
}
Sstack_main.c
#include "sstack.h"
int main()
{
// 声明顺序栈
SeqStack st;
// 声明一个变量,用来接收弹出的数据
DATA data;
// 初始化顺序栈
SStack_init(&st,10);
for(int i = 0;i<15;i++)
{
// 入栈
SStack_push(&st,i);
}
// 弹栈
while(!SStack_isempty(&st))
{
SStack_pop(&st,&data);
printf("%-4d",data);
}
printf("\n");
printf("====回收栈====\n");
SStack_destroy(&st);
return 0;
}