目录
栈具有后入先出(LIFO)特性
有函数调用、括号匹配等等等等多种用途,数不胜数,总之就是非常有用
栈分为顺序栈和链栈(静态分配空间和动态分配空间的区别)
顺序栈(C):
#include <stdio.h>
#include <stdlib.h>
#define MAXSIZE 10 //最大栈深
typedef int ElemType;
typedef struct {
int data[MAXSIZE]; //栈元素
int top; //栈顶指针
}SqStack;
//初始化顺序栈
void InitStack(SqStack* S)
{
S->top = -1;//初始化栈顶指针,指向当前栈顶数据,-1表示空栈
}
//顺序栈无需手动销毁
//栈判空
int StackEmpty(SqStack S)
{
if (S.top == -1)
return 1;
else
return 0;
}
//元素进栈
int Push(SqStack* S, ElemType e)
{
if (S->top == MAXSIZE - 1)
return 0; //栈满不能入栈
S->data[++(S->top)] = e;
return 1;
}
//元素出栈,并获取出栈元素
int Pop(SqStack* S, ElemType* e)
{
if (S->top == -1)
return 0; //栈空不能出栈
*e = S->data[S->top--];
return 1;
}
//获取栈顶元素
int GetTop(SqStack S, ElemType* e)
{
if (S.top == -1)
return 0;
*e = S.data[S.top];
return 1;
}
int main()
{
SqStack S;
InitStack(&S);//初始化栈
//判断栈是否为空
if (StackEmpty(S)) {
printf("栈为空!\n");
}
else {
printf("栈非空!\n\n\n");
}
//进栈
if (Push(&S, 100)) {
printf("100进栈成功!\n");
}
else {
printf("100进栈失败!\n");
}
if (Push(&S, 200)) {
printf("200进栈成功!\n");
}
else {
printf("200进栈失败!\n");
}
if (Push(&S, 300)) {
printf("300进栈成功!\n");
}
else {
printf("300进栈失败!\n");
}
//判断栈是否为空
if (StackEmpty(S)) {
printf("栈为空!\n");
}
else {
printf("栈非空!\n\n\n");
}
//读取栈顶元素
int temp;
if (GetTop(S, &temp)) {
printf("栈顶元素为:%d\n", temp);
}
else {
printf("读取栈顶元素出错!\n");
}
//出栈&读取栈顶元素
if (Pop(&S, &temp)) {
printf("%d出栈成功!\n", temp);
}
else {
printf("出栈失败!\n");
}
if (GetTop(S, &temp)) {
printf("栈顶元素为:%d\n", temp);
}
else {
printf("读取栈顶元素出错!\n");
}
//出栈&读取栈顶元素
if (Pop(&S, &temp)) {
printf("%d出栈成功!\n", temp);
}
else {
printf("出栈失败!\n");
}
if (GetTop(S, &temp)) {
printf("栈顶元素为:%d\n", temp);
}
else {
printf("读取栈顶元素出错!\n");
}
//出栈&读取栈顶元素
if (Pop(&S, &temp)) {
printf("%d出栈成功!\n", temp);
}
else {
printf("出栈失败!\n");
}
if (GetTop(S, &temp)) {
printf("栈顶元素为:%d\n", temp);
}
else {
printf("读取栈顶元素出错!\n");
}
//出栈&读取栈顶元素
if (Pop(&S, &temp)) {
printf("%d出栈成功!\n", temp);
}
else {
printf("出栈失败!\n");
}
if (GetTop(S, &temp)) {
printf("栈顶元素为:%d\n", temp);
}
else {
printf("读取栈顶元素出错!\n\n\n");
}
//判断栈是否为空
if (StackEmpty(S)) {
printf("栈为空!\n");
}
else {
printf("栈非空!\n\n\n");
}
system("pause");
return 0;
}
顺序栈(C++):
#include <iostream>
#define MAXSIZE 10 //最大栈深
typedef int ElemType;
typedef struct {
int data[MAXSIZE]; //栈元素
int top; //栈顶指针
}SqStack;
//初始化顺序栈
void InitStack(SqStack& S)
{
S.top = -1;//初始化栈顶指针,指向当前栈顶数据,-1表示空栈
}
//顺序栈无需手动销毁
//栈判空
bool StackEmpty(SqStack S)
{
if (S.top == -1)
return true;
else
return false;
}
//元素进栈
bool Push(SqStack& S, ElemType e)
{
if (S.top == MAXSIZE - 1)
return false; //栈满不能入栈
S.data[++S.top] = e;
return true;
}
//元素出栈,并获取出栈元素
bool Pop(SqStack& S, ElemType& e)
{
if (S.top == -1)
return false; //栈空不能出栈
e = S.data[S.top--];
return true;
}
//获取栈顶元素
bool GetTop(SqStack S, ElemType& e)
{
if (S.top == -1)
return false;
e = S.data[S.top];
return true;
}
int main()
{
SqStack S;
InitStack(S);//初始化栈
//判断栈是否为空
if (StackEmpty(S)) {
std::cout << "栈为空!\n";
}
else {
std::cout << "栈非空!\n\n\n";
}
//进栈
if (Push(S, 100)) {
std::cout << "100进栈成功!\n";
}
else {
std::cout << "100进栈失败!\n";
}
if (Push(S, 200)) {
std::cout << "200进栈成功!\n";
}
else {
std::cout << "200进栈失败!\n";
}
if (Push(S, 300)) {
std::cout << "300进栈成功!\n";
}
else {
std::cout << "300进栈失败!\n";
}
//判断栈是否为空
if (StackEmpty(S)) {
std::cout << "栈为空!\n";
}
else {
std::cout << "栈非空!\n\n\n";
}
//读取栈顶元素
int temp;
if (GetTop(S, temp)) {
std::cout << "栈顶元素为:" << temp << std::endl;
}
else {
std::cout << "读取栈顶元素出错!\n";
}
//出栈&读取栈顶元素
if (Pop(S, temp)) {
std::cout << temp << "出栈成功!\n";
}
else {
std::cout << "出栈失败!\n";
}
if (GetTop(S, temp)) {
std::cout << "栈顶元素为:" << temp << std::endl;
}
else {
std::cout << "读取栈顶元素出错!\n";
}
//出栈&读取栈顶元素
if (Pop(S, temp)) {
std::cout << temp << "出栈成功!\n";
}
else {
std::cout << "出栈失败!\n";
}
if (GetTop(S, temp)) {
std::cout << "栈顶元素为:" << temp << std::endl;
}
else {
std::cout << "读取栈顶元素出错!\n";
}
//出栈&读取栈顶元素
if (Pop(S, temp)) {
std::cout << temp << "出栈成功!\n";
}
else {
std::cout << "出栈失败!\n";
}
if (GetTop(S, temp)) {
std::cout << "栈顶元素为:" << temp << std::endl;
}
else {
std::cout << "读取栈顶元素出错!\n";
}
//出栈&读取栈顶元素
if (Pop(S, temp)) {
std::cout << temp << "出栈成功!\n";
}
else {
std::cout << "出栈失败!\n";
}
if (GetTop(S, temp)) {
std::cout << "栈顶元素为:" << temp << std::endl;
}
else {
std::cout << "读取栈顶元素出错!\n";
}
//判断栈是否为空
if (StackEmpty(S)) {
std::cout << "栈为空!\n";
}
else {
std::cout << "栈非空!\n\n\n";
}
system("pause");
return 0;
}
顺序栈测试结果:
带头结点链栈(C):
#include <stdio.h>
#include <stdlib.h>
typedef int ElemType;
typedef struct LiStack {
ElemType data; //数据域
struct LiStack* next;//指针域
}LiStack;
//初始化链栈,此处为带头结点链栈
int InitLiStack(LiStack** S)//注意此处使用二级指针
{
LiStack* p = (LiStack*)malloc(sizeof(LiStack));//头结点
if (p == NULL) return 0;
p->next = NULL;
*S = p;
return 1;
}
//销毁链栈
int DestroyLiStack(LiStack** S)
{
if ((*S)->next == NULL) //空栈
return 0;
LiStack* p;
while ((*S)->next != NULL) {
p = (*S)->next;//p指向待删除结点
(*S)->next = p->next;
free(p);
}
return 1;
}
//判空
int LiStackEmpty(LiStack* S)
{
if (S->next == NULL)
return 1;
else
return 0;
}
//入栈
int Push(LiStack** S, ElemType x)
{
//不存在栈满情况
LiStack* p = (LiStack*)malloc(sizeof(LiStack));
p->data = x;
p->next = (*S)->next;
(*S)->next = p;
return 1;
}
//出栈
int Pop(LiStack** S, ElemType* x)
{
if ((*S)->next == NULL)
return 0; //栈空
LiStack* p = (*S)->next;//p指向待删除结点
*x = p->data;
(*S)->next = p->next;
free(p);
p = NULL;
return 1;
}
//获取栈顶元素
int GetTop(LiStack* S, ElemType* x)
{
if (S->next == NULL)
return 0;
*x = S->next->data;
return 1;
}
int main()
{
LiStack* Lhead; //链栈头指针
InitLiStack(&Lhead);//初始化栈
//判断栈是否为空
if (LiStackEmpty(Lhead)) {
printf("栈为空!\n");
}
else {
printf("栈非空!\n\n\n");
}
//进栈
if (Push(&Lhead, 100)) {
printf("100进栈成功!\n");
}
else {
printf("100进栈失败!\n");
}
if (Push(&Lhead, 200)) {
printf("200进栈成功!\n");
}
else {
printf("200进栈失败!\n");
}
if (Push(&Lhead, 300)) {
printf("300进栈成功!\n");
}
else {
printf("300进栈失败!\n");
}
//判断栈是否为空
if (LiStackEmpty(Lhead)) {
printf("栈为空!\n");
}
else {
printf("栈非空!\n\n\n");
}
//读取栈顶元素
ElemType temp;
if (GetTop(Lhead, &temp)) {
printf("栈顶元素为:%d\n", temp);
}
else {
printf("读取栈顶元素出错!\n");
}
//出栈&读取栈顶元素
if (Pop(&Lhead, &temp)) {
printf("%d出栈成功!\n", temp);
}
else {
printf("出栈失败!\n");
}
if (GetTop(Lhead, &temp)) {
printf("栈顶元素为:%d\n", temp);
}
else {
printf("读取栈顶元素出错!\n");
}
//出栈&读取栈顶元素
if (Pop(&Lhead, &temp)) {
printf("%d出栈成功!\n", temp);
}
else {
printf("出栈失败!\n");
}
if (GetTop(Lhead, &temp)) {
printf("栈顶元素为:%d\n", temp);
}
else {
printf("读取栈顶元素出错!\n");
}
printf("\n");
//销毁栈
if (DestroyLiStack(&Lhead)) {
printf("销毁栈成功!\n");
}
else {
printf("销毁栈失败!\n");
}
//出栈&读取栈顶元素
if (Pop(&Lhead, &temp)) {
printf("%d出栈成功!\n", temp);
}
else {
printf("出栈失败!\n");
}
if (GetTop(Lhead, &temp)) {
printf("栈顶元素为:%d\n", temp);
}
else {
printf("读取栈顶元素出错!\n");
}
//判断栈是否为空
if (LiStackEmpty(Lhead)) {
printf("栈为空!\n");
}
else {
printf("栈非空!\n\n\n");
}
system("pause");
return 0;
}
不带头结点链栈(C):
#include <stdio.h>
#include <stdlib.h>
typedef int ElemType;
typedef struct LiStack {
ElemType data; //数据域
struct LiStack* next;//指针域
}LiStack;
//初始化链栈,此处为不带头结点链栈
int InitLiStack(LiStack** S)//注意此处使用二级指针
{
*S = NULL;//头指针指向空,表示为空栈
return 1;
}
//销毁链栈
int DestroyLiStack(LiStack** S)
{
if (*S == NULL) return 0;//空栈
LiStack* p;
while (*S != NULL) {
p = *S;//p指向待删除结点
*S = (*S)->next;
free(p);
}
return 1;
}
//判空
int LiStackEmpty(LiStack* S)
{
if (S == NULL)
return 1;
else
return 0;
}
//入栈
int Push(LiStack** S, ElemType x)
{
//不存在栈满情况
LiStack* p = (LiStack*)malloc(sizeof(LiStack));
if (p == NULL) return 0;
if (*S == NULL) {//若为空栈
p->next = NULL;
*S = p;
return 1;
}
else {
p->next = *S;
*S = p;
return 1;
}
}
//出栈
int Pop(LiStack** S, ElemType* x)
{
if (*S == NULL)
return 0; //栈空
LiStack* p = *S;//p指向待出栈结点
*x = p->data;
*S = (*S)->next;
free(p);
p = NULL;
return 1;
}
//获取栈顶元素
int GetTop(LiStack* S, ElemType* x)
{
if (S == NULL)
return 0;
*x = S->data;
return 1;
}
int main()
{
LiStack* Lhead; //链栈头指针
InitLiStack(&Lhead);//初始化栈
//判断栈是否为空
if (LiStackEmpty(Lhead)) {
printf("栈为空!\n");
}
else {
printf("栈非空!\n\n\n");
}
//进栈
if (Push(&Lhead, 100)) {
printf("100进栈成功!\n");
}
else {
printf("100进栈失败!\n");
}
if (Push(&Lhead, 200)) {
printf("200进栈成功!\n");
}
else {
printf("200进栈失败!\n");
}
if (Push(&Lhead, 300)) {
printf("300进栈成功!\n");
}
else {
printf("300进栈失败!\n");
}
//判断栈是否为空
if (LiStackEmpty(Lhead)) {
printf("栈为空!\n");
}
else {
printf("栈非空!\n\n\n");
}
//读取栈顶元素
ElemType temp;
if (GetTop(Lhead, &temp)) {
printf("栈顶元素为:%d\n", temp);
}
else {
printf("读取栈顶元素出错!\n");
}
//出栈&读取栈顶元素
if (Pop(&Lhead, &temp)) {
printf("%d出栈成功!\n", temp);
}
else {
printf("出栈失败!\n");
}
if (GetTop(Lhead, &temp)) {
printf("栈顶元素为:%d\n", temp);
}
else {
printf("读取栈顶元素出错!\n");
}
//出栈&读取栈顶元素
if (Pop(&Lhead, &temp)) {
printf("%d出栈成功!\n", temp);
}
else {
printf("出栈失败!\n");
}
if (GetTop(Lhead, &temp)) {
printf("栈顶元素为:%d\n", temp);
}
else {
printf("读取栈顶元素出错!\n");
}
printf("\n");
//销毁栈
if (DestroyLiStack(&Lhead)) {
printf("销毁栈成功!\n");
}
else {
printf("销毁栈失败!\n");
}
//出栈&读取栈顶元素
if (Pop(&Lhead, &temp)) {
printf("%d出栈成功!\n", temp);
}
else {
printf("出栈失败!\n");
}
if (GetTop(Lhead, &temp)) {
printf("栈顶元素为:%d\n", temp);
}
else {
printf("读取栈顶元素出错!\n");
}
//判断栈是否为空
if (LiStackEmpty(Lhead)) {
printf("栈为空!\n");
}
else {
printf("栈非空!\n\n\n");
}
system("pause");
return 0;
}
带头结点链栈(C++):
#include <iostream>
typedef int ElemType;
typedef struct LiStack {
ElemType data; //数据域
struct LiStack* next;//指针域
}LiStack;
//初始化链栈,此处为带头结点链栈
bool InitLiStack(LiStack*& S)
{
LiStack* p = new LiStack;//头结点
if (p == NULL) return false;
p->next = NULL;
S = p;
return true;
}
//销毁链栈
bool DestroyLiStack(LiStack*& S)
{
if (S->next == NULL) //空栈
return false;
LiStack* p;
while (S->next != NULL) {
p = S->next;//p指向待删除结点
S->next = p->next;
free(p);
}
return true;
}
//判空
bool LiStackEmpty(LiStack* S)
{
if (S->next == NULL)
return true;
else
return false;
}
//入栈
bool Push(LiStack*& S, ElemType x)
{
//不存在栈满情况
LiStack* p = new LiStack;
p->data = x;
p->next = S->next;
S->next = p;
return true;
}
//出栈
bool Pop(LiStack*& S, ElemType& x)
{
if (S->next == NULL)
return false; //栈空
LiStack* p = S->next;//p指向待删除结点
x = p->data;
S->next = p->next;
free(p);
p = NULL;
return true;
}
//获取栈顶元素
bool GetTop(LiStack* S, ElemType& x)
{
if (S->next == NULL)
return false;
x = S->next->data;
return true;
}
int main()
{
LiStack* Lhead; //链栈头指针
InitLiStack(Lhead);//初始化栈
//判断栈是否为空
if (LiStackEmpty(Lhead)) {
std::cout << "栈为空!\n";
}
else {
std::cout << "栈非空!\n\n\n";
}
//进栈
if (Push(Lhead, 100)) {
std::cout << "100进栈成功!\n";
}
else {
std::cout << "100进栈失败!\n";
}
if (Push(Lhead, 200)) {
std::cout << "200进栈成功!\n";
}
else {
std::cout << "200进栈失败!\n";
}
if (Push(Lhead, 300)) {
std::cout << "300进栈成功!\n";
}
else {
std::cout << "300进栈失败!\n";
}
//判断栈是否为空
if (LiStackEmpty(Lhead)) {
std::cout << "栈为空!\n";
}
else {
std::cout << "栈非空!\n\n\n";
}
//读取栈顶元素
ElemType temp;
if (GetTop(Lhead, temp)) {
std::cout << "栈顶元素为:" << temp << std::endl;
}
else {
std::cout << "读取栈顶元素出错!\n";
}
//出栈&读取栈顶元素
if (Pop(Lhead, temp)) {
std::cout << temp << "出栈成功!\n";
}
else {
std::cout << "出栈失败!\n";
}
if (GetTop(Lhead, temp)) {
std::cout << "栈顶元素为:" << temp << std::endl;
}
else {
std::cout << "读取栈顶元素出错!\n";
}
//出栈&读取栈顶元素
if (Pop(Lhead, temp)) {
std::cout << temp << "出栈成功!\n";
}
else {
std::cout << "出栈失败!\n";
}
if (GetTop(Lhead, temp)) {
std::cout << "栈顶元素为:" << temp << std::endl << std::endl;
}
else {
std::cout << "读取栈顶元素出错!\n";
}
//销毁栈
if (DestroyLiStack(Lhead)) {
std::cout << "销毁栈成功!\n";
}
else {
std::cout << "销毁栈失败!\n";
}
//出栈&读取栈顶元素
if (Pop(Lhead, temp)) {
std::cout << temp << "出栈成功!\n";
}
else {
std::cout << "出栈失败!\n";
}
if (GetTop(Lhead, temp)) {
std::cout << "栈顶元素为:" << temp << std::endl;
}
else {
std::cout << "读取栈顶元素出错!\n";
}
if (LiStackEmpty(Lhead)) {
std::cout << "栈为空!\n";
}
else {
std::cout << "栈非空!\n\n\n";
}
system("pause");
return 0;
}
不带头结点链栈(C++):
#include <iostream>
typedef int ElemType;
typedef struct LiStack{
ElemType data; //数据域
struct LiStack* next; //指针域
}LiStack;
//初始化链栈,此处为不带头结点链栈
bool InitLiStack(LiStack*& S)//引用一个链栈指针
{
S = NULL;//头指针指向空,表示为空栈
return true;
}
//销毁栈
bool DestroyLiStack(LiStack*& S)
{
if (S == NULL) return false;//空栈
LiStack* p;
while (S != NULL) {
p = S; //p指向待删除结点
S = S->next;
free(p);
}
return true;
}
//栈判空
bool LiStackEmpty(LiStack*& S)
{
if (S == NULL)
return true;
else
return false;
}
//进栈(链栈不存在栈满情况)
bool Push(LiStack*& S, ElemType x)
{
LiStack* p = new LiStack;//待入栈结点
p->data = x;
if (S == NULL) {//若为空栈
p->next = NULL;
S = p;
return true;
}
else {
p->next = S;
S = p;
return true;
}
}
//出栈
bool Pop(LiStack*& S, ElemType& x)
{
if (S == NULL)
return false;//若为空栈,则出错
LiStack* p = S;//p指向待出栈结点
S = S->next;//更改头指针
x = p->data;
free(p);
p = NULL;
return true;
}
//获取栈顶值
bool GetTop(LiStack* S, ElemType& x)
{
if (S == NULL)
return false;//若为空栈,则出错
x = S->data;
return true;
}
int main()
{
LiStack* Lhead; //链栈头指针
InitLiStack(Lhead);//初始化栈
//判断栈是否为空
if (LiStackEmpty(Lhead)) {
std::cout << "栈为空!\n";
}
else {
std::cout << "栈非空!\n\n\n";
}
//进栈
if (Push(Lhead, 100)) {
std::cout << "100进栈成功!\n";
}
else {
std::cout << "100进栈失败!\n";
}
if (Push(Lhead, 200)) {
std::cout << "200进栈成功!\n";
}
else {
std::cout << "200进栈失败!\n";
}
if (Push(Lhead, 300)) {
std::cout << "300进栈成功!\n";
}
else {
std::cout << "300进栈失败!\n";
}
//判断栈是否为空
if (LiStackEmpty(Lhead)) {
std::cout << "栈为空!\n";
}
else {
std::cout << "栈非空!\n\n\n";
}
//读取栈顶元素
ElemType temp;
if (GetTop(Lhead, temp)) {
std::cout << "栈顶元素为:" << temp << std::endl;
}
else {
std::cout << "读取栈顶元素出错!\n";
}
//出栈&读取栈顶元素
if (Pop(Lhead, temp)) {
std::cout << temp << "出栈成功!\n";
}
else {
std::cout << "出栈失败!\n";
}
if (GetTop(Lhead, temp)) {
std::cout << "栈顶元素为:" << temp << std::endl;
}
else {
std::cout << "读取栈顶元素出错!\n";
}
//出栈&读取栈顶元素
if (Pop(Lhead, temp)) {
std::cout << temp << "出栈成功!\n";
}
else {
std::cout << "出栈失败!\n";
}
if (GetTop(Lhead, temp)) {
std::cout << "栈顶元素为:" << temp << std::endl << std::endl;
}
else {
std::cout << "读取栈顶元素出错!\n";
}
//销毁栈
if (DestroyLiStack(Lhead)) {
std::cout << "销毁栈成功!\n";
}
else {
std::cout << "销毁栈失败!\n";
}
//出栈&读取栈顶元素
if (Pop(Lhead, temp)) {
std::cout << temp << "出栈成功!\n";
}
else {
std::cout << "出栈失败!\n";
}
if (GetTop(Lhead, temp)) {
std::cout << "栈顶元素为:" << temp << std::endl;
}
else {
std::cout << "读取栈顶元素出错!\n";
}
if (LiStackEmpty(Lhead)) {
std::cout << "栈为空!\n";
}
else {
std::cout << "栈非空!\n\n\n";
}
system("pause");
return 0;
}
链栈测试结果:
总结:
注意搞清楚带头结点以及不带头结点的操作不同之处(主要在于处理头指针处)
以上均为个人学习心得,如有错误,请不吝赐教~
THE END