栈以及栈的应用

一、写在前面的话

        本文为作者学习笔记留存,如有侵权,私信我删。

        总所周知,链表头插为栈。故以下所有示例中都为链栈,且都是不带头结点的链表。

二、栈的实现 

        对于栈的测试使用在这里就先不测了,如有需要,各位大佬自行测试哦!

#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;
}

  • 8
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值