#include <stdio.h>
#include <malloc.h>
#include <stdlib.h>
typedef struct Node //定义链表结点
{
int data;
struct Node * pNext;
}NODE, *PNODE;
typedef struct Stack //定义栈
{
PNODE pTop; //定义第一个结构体名为 栈顶
PNODE pBottom; //定义第二个结构体名为 栈底
}STACK, *PSTACK;
void init(PSTACK pS);
void push(PSTACK, int val);
void traverse(PSTACK pS);
bool clear(PSTACK pS);
bool pop(PSTACK pS, int * pval);
int main(void)
{
STACK S; //定义栈名为S
int val; //用来获取接收某个值
init(&S); //创造一个空栈
push(&S, 1); //压栈或叫入栈
/*push(&S, 2);
push(&S, 3);
push(&S, 4);
push(&S, 5);
push(&S, 6); */
traverse(&S); //遍历输出
if (pop(&S, &val))
{
printf("出栈成功,出栈的元素是%d\n", val);
}
else
{
printf("出栈失败\n");
}
if (clear(&S))
{
printf("栈清空成功\n");
}
else
{
printf("栈清空失败\n");
}
return 0;
}
void init(PSTACK pS)
{
pS->pTop = (PNODE)malloc(sizeof(NODE)); // 动态分配一片内存空间
if (NULL == pS->pTop) // 判断是否为空可使算法更高效
{
printf("动态内存分配失败\n");
exit(-1);
}
else
{
pS->pBottom = pS->pTop; // 若栈顶和栈底指向同一个结点,则证明该栈为空栈
pS->pTop->pNext = NULL; // 栈初始化栈顶指向地址为空
}
}
void push(PSTACK pS, int val)
{
PNODE pNew = (PNODE)malloc(sizeof(NODE));
pNew->data = val; // pNew的数据域是赋的值
pNew->pNext = pS->pTop; // 让pNew的指针域指向pTop
pS->pTop = pNew; // pNew成为新的pTop
return;
}
void traverse(PSTACK pS)
{
PNODE p = pS->pTop; /*遍历思想:先定义一个 p与 pTop一样指向栈顶结点,输出 p->data的值,
然后让 p指向原来的结点的下一个结点,直到 p与 pBottom指向相同地址*/
while (p != pS->pBottom)
{
printf("%d ", p->data);
p = p->pNext;
}
printf("\n");
return;
}
bool empty(PSTACK pS)
{
if (pS->pTop == pS->pBottom)
return true;
else
return false;
}
bool clear(PSTACK pS)
{
if (empty(pS)) // pS本身就是存放的S的地址,前面无需加*
{
printf("栈为空,无需清空\n");
return false;
}
else
{
PNODE p = pS->pTop; /*栈清空思想:需要设立两个变量 p, q 一个变量无法找到释放结点的下
一个结点,所以需要用 q来保存下一个结点的地址, p从栈顶开始,当 p
指向栈底时结束*/
PNODE q = NULL;
while (p != pS->pBottom)
{
q = p->pNext;
free(p);
p = q;
}
pS->pTop = pS->pBottom;
return true;
}
}
bool pop(PSTACK pS, int * pval) // 把 pS所指向的栈出栈一次
{
if (empty(pS))
{
return false; //出栈失败返回 false
}
else
{
PNODE r = pS->pTop; // 首先定义变量 r指向栈顶
* pval = r->data; // 用 val保存出栈元素r的数据
pS->pTop = r->pNext; /* 然后将 r指向的下一个结点地址赋给栈顶, 即 r指向的下一个结点
成为新的栈顶 */
free(r); // 释放 r现在指向结点的内存
r = NULL; // 把 r赋为空, 避免垃圾值
return true;
}
}
【数据结构】栈的创建、入栈、出栈、栈的清空
于 2022-03-19 16:54:19 首次发布