六、C语言实现栈的基本功能
1、栈的原则:
先进后出,后进先出
2、声明
#pragma once
//结构声明
typedef int Element;
typedef struct Stack
{
int size; //栈容量
int top; //栈顶下标
Element* stack_low; //栈底指针
}Stack,*PStack; //PStack可用来定义指针类型的栈
//栈扩容
bool ApplyNewSpace(Stack* st);
//初始化栈
void InitStack(Stack* st, int init_size);
//判栈满
bool StackIsFull(Stack* st);
//判空
bool StackIsEmpty(Stack* st);
//入栈
void PushStack(Stack* st, Element value);
//出栈
void PopStack(Stack* st);
//求栈顶元素
Element TopElem(Stack* st, Element* reval);
//销毁栈
void DestroyStack(Stack* st);
//输出栈中元素
void ShowStack(Stack* st);
//栈功能测试
void StackTest(void);
3、方法实现
#include "Stack.h"
#include <stdlib.h>
#include <malloc.h>
#include <stdio.h>
//栈扩容
bool ApplyNewSpace(Stack* st)
{
if (st == NULL) return false;
//栈里的数据类型是Element
Element* newspace = (Element*)malloc(sizeof(Element) * st->size * 2);
if (newspace == NULL) return false;
//转移数据
for (int i = 0; i < st->size; i++)
{
newspace[i] = st->stack_low[i];
}
free(st->stack_low);
st->stack_low = newspace;
st->size *= 2;
}
//初始化栈
void InitStack(Stack* st, int init_size)
{
if (st == NULL) exit(0);
init_size = init_size > 0 ? init_size : 10;
st->stack_low = (Element*)malloc(sizeof(Element)*init_size);
if (st->stack_low == NULL) exit(0);
st->top = 0;
st->size = init_size;
}
//判栈满
bool StackIsFull(Stack* st)
{
if (st == NULL) exit(0);
return st->size == st->top;
}
//判空
bool StackIsEmpty(Stack* st)
{
if (st == NULL) exit(0);
return st->top == 0;
}
//入栈
void PushStack(Stack *st, Element value)
{
if (st == NULL) exit(0);
if (StackIsFull(st)&& !ApplyNewSpace(st)) exit(0);
st->stack_low[st->top++] = value;
}
//出栈
void PopStack(Stack* st)
{
if (st == NULL) exit(0);
if (StackIsEmpty(st)) exit(0);
st->top--;
}
//求栈顶元素
Element TopElem(Stack *st,Element *reval)
{
if (st == NULL) exit(0);
if (StackIsEmpty(st)) exit(0);
*reval = st->stack_low[st->top-1];
return *reval;
}
//销毁栈
void DestroyStack(Stack* st)
{
if (st == NULL) exit(0);
//栈中元素的数据值可以不做处理
free(st->stack_low);
st->stack_low = NULL;
st->size = 0;
st->top = 0;
}
//输出栈中元素
void ShowStack(Stack* st)
{
if (st == NULL) exit(0);
while (!StackIsEmpty(st))
{
Element tmp = 0;
printf("%d ", TopElem(st, &tmp));
PopStack(st);
}
printf("\n");
}
//栈功能测试
void StackTest(void)
{
Stack st;
InitStack(&st, 10);
printf("入栈:13 56 28 77 12 42 78 32 66 42 29\n");
PushStack(&st, 13);
PushStack(&st, 56);
PushStack(&st, 28);
PushStack(&st, 77);
PushStack(&st, 12);
PushStack(&st, 42);
PushStack(&st, 78);
PushStack(&st, 32);
PushStack(&st, 66);
PushStack(&st, 42);
PushStack(&st, 29);
printf("出栈:");
//ShowStack中有Pop有Stack操作
ShowStack(&st);
DestroyStack(&st);
}
4、主函数测试
#include "Stack.h"
int main()
{
StackTest();
return 0;
}
5、测试结果
6、注意事项
栈空间结构体中包含:(int)栈容量大小、(存储数据的类型)栈底指针、以及(int)栈顶top下标
本文中的输出(ShowStack)会Pop掉栈中所有元素,所以要想实现既能够输出,还要保留栈中元素,就得设置flag来保存top下标,输出用top- -来实现,这样就不会Pop掉所有元素。
改后的代码实现如下
//输出栈中元素
void ShowStack(Stack* st)
{
if (st == NULL) exit(0);
/*while (!StackIsEmpty(st))
{
Element tmp = 0;
printf("%d ", TopElem(st, &tmp));
PopStack(st);
}*/
int flag = st->top;
while (st->top > 0)
{
printf("%d ", st->stack_low[st->top-1]);
st->top--;
}
st->top = flag;
printf("\n");
}
//栈功能测试
void StackTest(void)
{
Stack st;
InitStack(&st, 10);
printf("入栈:13 56 28 77 12 47 78 32 66 42 29\n");
PushStack(&st, 13);
PushStack(&st, 56);
PushStack(&st, 28);
PushStack(&st, 77);
PushStack(&st, 12);
PushStack(&st, 47);
PushStack(&st, 78);
PushStack(&st, 32);
PushStack(&st, 66);
PushStack(&st, 42);
PushStack(&st, 29);
printf("出栈:");
ShowStack(&st);
printf("\n");
printf("在执行Pop5次, 出栈的元素为29 42 66 32 78 \n");
for(int i=0;i<5;i++)
{
PopStack(&st);
}
printf("出栈为:");
ShowStack(&st);
DestroyStack(&st);
}
此次结果:
所以栈作为一种线性得数据结构,就好比是一把钳子,想怎么用,看你自己怎么实现。😉