一、写在前面的话
本文为作者学习笔记留存,如有侵权,私信我删。
总所周知,链表头插为栈。故以下所有示例中都为链栈,且都是不带头结点的链表。
二、栈的实现
对于栈的测试使用在这里就先不测了,如有需要,各位大佬自行测试哦!
#include <stdio.h>
#include <stdlib.h>
#include <stdbool.h>
typedef struct Node {
int data;
struct Node *next;
} Node; //结点定义
typedef struct Stack {
Node *top;
int count;
} Stack; //栈定义
/*结点相关操作*/
Node *getNewNode(int data) {
Node *node = (Node *)malloc(sizeof(Node));
if (node == NULL) {
printf("申请空间错误!\n");
exit(0);
}
node->data = data;
node->next = NULL;
return node;
} //创建一个新结点
void delNode(Node *node) {
free(node);
node = NULL;
} //删除一个结点
/*栈相关操作*/
Stack *initStack() {
Stack *stack = (Stack *)malloc(sizeof(Stack));
stack->top = NULL;
stack->count = 0;
return stack;
} //初始化一个栈
bool isEmpty(Stack *stack) {
if (stack->count == 0) return true;
return false;
} //判断一个栈是否为空
bool pop(Stack *stack) {
if (isEmpty(stack)) return false; //栈空判断
Node *temp = stack->top;
stack->top = stack->top->next;
delNode(temp);
(stack->count)--;
return true;
} //弹栈
void push(Stack *stack, int data) {
Node *node = getNewNode(data);
node->next = stack->top;
stack->top = node;
(stack->count)++;
} //入栈
int getTop(Stack stack) {
return stack.top->data;
} //查看栈顶
void output(Stack stack) {
while (stack.top) {
printf("%d ", getTop(stack));
stack.top = stack.top->next;
}
printf("\n");
} //遍历输出栈的内容
void destoryStack(Stack *stack) {
if (stack->count != 0) {
int count = stack->count;
int i;
for (i = 0; i < count; i++) {
pop(stack);
}
} //栈不为空 先将所有数据出栈
free(stack);
stack = NULL;
} //摧毁栈
三、进制转换
在将十进制转换为其他进制的过程中,我们可以使用栈来存储每一位的余数,最后将余数倒序输出即可得到转换结果。
具体的十进制转二进制的过程在这里就不多赘述了,如有问题,可查阅相关资料。代码示例为十进制转二进制。
void decToBin(int number) {
Stack *stack = initStack();
int dis; //商
int rem = number; //余数
while (rem) {
dis = rem % 2;
push(stack, dis);
rem = rem / 2;
}
printf("输出对应的二进制数为: ");
output(*stack);
}
以下内容可以不看,不涉及栈的内容。
#include <math.h>
//二进制转十进制
void binToDec(int number) {
int cnt = 0;
int res = 0;
int dis = number; //商
int rem; //余数
while (dis) {
int temp = pow(2.0, cnt);
rem = dis % 10;
res += rem * temp;
cnt++;
dis /= 10;
}
printf("输出对应的十进制数为: %d\n", res);
}
四、括号匹配
目的:检验表达式中的括号是否匹配。eg:括号'('和括号')'匹配,括号'('和括号']'不匹配。
算法:在算法中设置一个栈,依次读入一个括号。若为左括号,入栈;若为右括号,则检查栈顶元素与当前括号是否匹配,若匹配,栈顶元素出栈,若不匹配,当前栈顶元素入栈(也就是不可能再匹配了)。通过判断栈的最终情况(是否为空)来确定括号是否匹配。
ps:演示代码展示如下,供与各位大佬交流。
#include <stdio.h>
#include <stdlib.h>
#include <stdbool.h>
typedef struct Node {
char data;
struct Node *next;
} Node; //结点定义
typedef struct Stack {
Node *top;
int count;
} Stack; //栈定义
/*结点相关操作*/
Node *getNewNode(char data) {
Node *node = (Node *)malloc(sizeof(Node));
if (node == NULL) {
printf("申请空间错误!\n");
exit(0);
}
node->data = data;
node->next = NULL;
return node;
} //创建一个新结点
void delNode(Node *node) {
free(node);
node = NULL;
} //删除一个结点
/*栈相关操作*/
Stack *initStack() {
Stack *stack = (Stack *)malloc(sizeof(Stack));
stack->top = NULL;
stack->count = 0;
return stack;
} //初始化一个栈
bool isEmpty(Stack *stack) {
if (stack->count == 0) return true;
return false;
} //判断一个栈是否为空
bool pop(Stack *stack) {
if (isEmpty(stack)) return false; //栈空判断
Node *temp = stack->top;
stack->top = stack->top->next;
delNode(temp);
(stack->count)--;
return true;
} //弹栈
void push(Stack *stack, char data) {
Node *node = getNewNode(data);
node->next = stack->top;
stack->top = node;
(stack->count)++;
} //入栈
char getTop(Stack stack) {
return stack.top->data;
} //查看栈顶
void output(Stack stack) {
while (stack.top) {
printf("%c ", getTop(stack));
stack.top = stack.top->next;
}
printf("\n");
} //遍历输出栈的内容
void destoryStack(Stack *stack) {
if (stack->count != 0) {
int count = stack->count;
int i;
for (i = 0; i < count; i++) {
pop(stack);
}
} //栈不为空 先将所有数据出栈
free(stack);
stack = NULL;
} //摧毁栈
/*括号匹配*/
void bracketMate(Stack *stack, char data) {
printf("当前的data为: %c ", data);
//左括号 入栈
if (data == '(' || data == '{' || data == '[') {
push(stack, data);
}
//括号匹配 出栈
else if (getTop(*stack) == '[' && data == ']') {
pop(stack);
}
else if (getTop(*stack) == '(' && data == ')') {
pop(stack);
}
else if (getTop(*stack) == '{' && data == '}') {
pop(stack);
}
//括号不匹配 捣乱
else {
push(stack, data);
}
printf("此时栈内数据为: ");
output(*stack);
}
int main() {
Stack *stack = initStack();
char datas[] = {'[', '[', ']', ']'};
int i;
for (i = 0; i < 4; i++) {
bracketMate(stack, datas[i]);
}
if (isEmpty(stack)) printf("括号匹配!\n");
else printf("括号不匹配!\n");
destoryStack(stack);
return 0;
}