C语言实现链栈基本操作(以括号是否配对为例)
通过调用简单函数实现顺序表的相关操作。代码编译环境为VS2019 16.9.4。因为VS的某些原因,scanf写为了scanf_s,作用是一样的,在其他编译环境中可将scanf_s改回去,gets_s同理。
代码功能:读入 一个字符串,判断其中的“{” 和 “}”,“[” 和 “]”,“(” 和 “)”是否配对
#include<stdio.h> //输入输出头文件
#include<stdlib.h> //标准头文件
#include<stdbool.h> //布尔类型头文件
#define MaxSize 9999
typedef char Elemtype; //该链栈中的元素为字符
typedef struct Stack* SqList; //将该链栈类型的指针命名为SqList
typedef struct Stack //定义链栈
{
Elemtype data; //存放栈中的数据元素
SqList next;
};
bool InitStack(SqList& s); //初始化栈
bool DestroyStack(SqList& s); //销毁栈
bool StackEmpty(SqList& s); //判断栈是否为空
bool Push(SqList& s, Elemtype e); //进栈
bool Pop(SqList& s, Elemtype& e); //出栈
bool GetTop(SqList s, Elemtype& e); //取栈顶元素
int main(int argc, const char* argv[])
{
SqList s;
Elemtype e;
char str[MaxSize];
bool flag = true; //默认字符串中的括号是配对的
InitStack(s); //初始化栈
printf("请输入一个字符串:\n");
gets_s(str, MaxSize);
for (int i = 0; str[i] != '\0'; i++) {
if (str[i] == '{' || str[i] == '[' || str[i] == '(') { //当为左括号时进栈左括号进栈
Push(s, str[i]);
}
else if (str[i] == '}' || str[i] == ']' || str[i] == ')') {
if (GetTop(s, e)) { //当栈不为空并且此时str[i]与栈顶元素相匹配时将栈顶元素出栈
if (e == '{' && str[i] == '}')
Pop(s, e);
else if (e == '[' && str[i] == ']')
Pop(s, e);
else if (e == '(' && str[i] == ')')
Pop(s, e);
else { //当str[i]与栈顶元素不匹配时,括号不配对
flag = false;
break;
}
}
else { //当栈已经为空时,右括号多余,括号不配对
flag = false;
break;
}
}
//当此时str[i]不为特定的括号时直接跳过
}
if (!StackEmpty(s)) //当栈不为空时,此时左括号多余,括号不配对
flag = false;
if (flag)
printf("在该字符串中,括号是配对的。\n");
else
printf("在该字符串中,括号不配对。\n");
DestroyStack(s); //销毁栈
return 0;
}
bool InitStack(SqList& s)
{
s = (SqList)malloc(sizeof(Stack));
//malloc有一定几率申请空间失败,此时继续申请,直到申请成功
while (!s) {
s = (SqList)malloc(sizeof(Stack));
}
s->next = NULL; //此时栈内无元素
return true;
}
bool DestroyStack(SqList& s)
{
SqList p;
p = s; //将p指向头结点
while (p) { //从头结点开始挨个释放,直到全部完成
s = s->next;
free(p);
p = s;
}
return true;
}
bool StackEmpty(SqList& s)
{
if (s->next == NULL) //当栈为空时返回“真”,否则返回“假”
return true;
else
return false;
}
bool Push(SqList& s, Elemtype e)
{
SqList p = (SqList)malloc(sizeof(Stack));
//malloc有一定几率申请空间失败,此时继续申请,直到申请成功
while (!p) {
p = (SqList)malloc(sizeof(Stack));
}
p->data = e; //把将要入栈的元素放入新的结点
p->next = s->next; //将新的结点用头插法插入
s->next = p;
return true;
}
bool Pop(SqList& s, Elemtype& e)
{
if (s->next == NULL) //当栈为空时无法出栈,返回“假”
return false;
SqList p; //p为工作指针
e = s->next->data; //记录出栈元素,通过引用参数带回
p = s->next; //将工作指针指向要出栈的结点
s->next = p->next; //将要出栈的结点从链栈中删除
free(p); //释放出栈的结点
return true;
}
bool GetTop(SqList s, Elemtype& e)
{
if (s->next == NULL) //当栈为空时栈内没有元素,返回“假”
return false;
e = s->next->data; //记录出栈的元素,并以引用参数带回
return true;
}
只要内存足够充足,理论上链栈不存在栈满的情况