栈和队列

#pragma once

#include<stdio.h>
#include<assert.h>
#include<stdlib.h>
#include<windows.h>

typedef int DataType;

//typedef char DataType;

//动态顺序栈
typedef struct Stack
{
	DataType* _arr;
	size_t _top;  //栈顶 -> 只可以在这一段进行插入和删除
	size_t _end;  //栈底
}Stack;

void StackInit(Stack *s);
void StackPush(Stack *s, DataType data);
void StackPop(Stack *s);
DataType StackTop(Stack *s);
void StackPrint(Stack *s);
int EmptyStack(Stack *s);
void StackSize(Stack *s);

///栈的应用/

//括号匹配问题
void MatchBrackets(char *buf, int len);
//逆波兰表达式
int ExpressionRPN(char *rpn, int len);
//寻找空格
int FindSpace(char *rpn, int pos, int len);
#include"Stack.h"

void StackInit(Stack *s)
{
	assert(s);
	s->_arr = NULL;
	s->_end = s->_top = 0;
}

void StackPush(Stack *s, DataType data)
{
	assert(s);
	if (s->_end == s->_top)
	{
		size_t size = s->_end > 0 ? 2 * s->_end : 3;
		s->_arr = (DataType*)realloc(s->_arr, sizeof(DataType) * size);
		assert(s->_arr);
		s->_end = size;
	}
	s->_arr[s->_top++] = data;
}

void StackPop(Stack *s)
{
	assert(s);
	if(s->_top)
		--s->_top;
}

DataType StackTop(Stack *s)
{
	assert(s);
	
	return s->_arr[s->_top - 1];
}

void StackPrint(Stack *s)
{
	size_t i = 0;
	assert(s);
	if (s->_top != 0)
	{
		for (i = 0; i < s->_top; ++i)
			printf("%d ", s->_arr[i]);

		printf("\n");
	}
	else
	{
		printf("栈为空\n");
	}
}

int EmptyStack(Stack *s)
{
	assert(s);
	//if (0 == s->_top)
	//	return 0;

	//return 1;

	return s->_top;

}

void StackSize(Stack *s)
{
	assert(s);

	printf("栈内数据个数为:%u \n", s->_top);
}

///栈的应用/

//括号匹配问题
void MatchBrackets(char *buf, int len)
{
	Stack s;
	StackInit(&s);
	int i = 0;
	assert(buf);
	for (i = 0; i < len; i++)
	{
		//如果是左括号,则将左括号入栈
		if (('(' == buf[i]) ||
			('[' == buf[i]) ||
			('{' == buf[i]))
		{
			StackPush(&s, buf[i]);
		}

		//如果是右括号,则与栈顶元素比较,如果匹配,则出栈进行下轮
		//若不匹配则直接退出
		if ((')' == buf[i]) ||
			(']' == buf[i]) ||
			('}' == buf[i]))
		{
			if (0 == EmptyStack(&s))
			{
				printf("不匹配,右括号多于左括号\n");
				return;
			}
			else
			{
				switch (buf[i])
				{
				case ')':
					if ('(' == StackTop(&s))
					{
						StackPop(&s);
						break;
					}
					else
					{
						printf("不匹配,左右括号次序不匹配\n");
						return;
					}

				case ']':
					if ('[' == StackTop(&s))
					{
						StackPop(&s);
						break;
					}
					else
					{
						printf("不匹配,左右括号次序不匹配\n");
						return;
					}

				case '}':
					if ('{' == StackTop(&s))
					{
						StackPop(&s);
						break;
					}
					else
					{
						printf("不匹配,左右括号次序不匹配\n");
						return;
					}

				default:
					return;
				}
			}
		}

	}

	//判断栈是否为空
	if (0 == EmptyStack(&s))
	{
		//若栈为空则匹配
		printf("括号匹配\n");
		return;

	}

	//栈不为空
	printf("不匹配,左括号多于右括号\n");
	return;
}



//寻找空格
int FindSpace(char *rpn, int pos, int len)
{
	for (; pos < len; ++pos)
	{
		if (' ' == rpn[pos])
			return pos;
	}

	return -1;
}
//逆波兰表达式
int ExpressionRPN(char *rpn, int len)
{
	int i = 0;
	//int num = 0;
	int rightnum = 0;
	int leftnum = 0;
	Stack s;
	StackInit(&s);
	assert(rpn);

	for (i = 0; i < len; ++i)
	{
		if (rpn[i] >= '0' && rpn[i] <= '9')
		{
			StackPush(&s, atoi(&rpn[i]));
			i = FindSpace(rpn, i, len);
			//continue;
		}
		if (('+' == rpn[i]) || ('-' == rpn[i]) || ('*' == rpn[i]) || ('/' == rpn[i]))
		{
			switch (rpn[i])
			{
			case '+':
				//先取右操作数,再出栈
				rightnum = StackTop(&s);
				StackPop(&s);
				//再取左操作数,再出栈
				leftnum = StackTop(&s);
				StackPop(&s);
				//将计算结果入栈
				StackPush(&s, leftnum + rightnum);
				break;

			case '-':
				//先取右操作数,再出栈
				rightnum = StackTop(&s);
				StackPop(&s);
				//再取左操作数,再出栈
				leftnum = StackTop(&s);
				StackPop(&s);
				//将计算结果入栈
				StackPush(&s, leftnum - rightnum);
				break;

			case '*':
				//先取右操作数,再出栈
				rightnum = StackTop(&s);
				StackPop(&s);
				//再取左操作数,再出栈
				leftnum = StackTop(&s);
				StackPop(&s);
				//将计算结果入栈
				StackPush(&s, leftnum * rightnum);
				break;

			case '/':
				//先取右操作数,再出栈
				rightnum = StackTop(&s);
				StackPop(&s);
				//再取左操作数,再出栈
				leftnum = StackTop(&s);
				StackPop(&s);
				//将计算结果入栈
				StackPush(&s, leftnum / rightnum);
				break;

			default:
				break;
			}
		}
	}

	//计算完毕,结果在栈里
	return StackTop(&s);
}
#pragma once

#include<stdio.h>
#include<assert.h>
#include<malloc.h>
#include<windows.h>

typedef char DataType;

//链式队列
typedef struct QueueNode
{
	DataType _data;
	struct QueueNode* _next;

}QueueNode;

typedef struct Queue
{
	QueueNode* _head;
	QueueNode* _tail;

}Queue;

QueueNode* BuyQueueNode(DataType data); //创建一个节点
void QueueInit(Queue* q); //初始化
void QueuePush(Queue* q, DataType data); //入队
void QueuePop(Queue* q); //出队
DataType QueueFront(Queue* q); //取队头
DataType QueueBack(Queue* q); //取队尾
void QueuePrint(Queue* q); //打印队列
void QueueSize(Queue* q); //求队列中的数据个数
int EmptyQueue(Queue* q); //判断队列是否为空
#include"Queue.h"

QueueNode* BuyQueueNode(DataType data) //创建一个节点
{
	QueueNode *newnode = NULL;
	newnode = (QueueNode*)malloc(sizeof(QueueNode));
	if (NULL == newnode)
	{
		printf("创建节点失败\n");
		return NULL;
		assert(newnode);
	}
	else
	{
		newnode->_data = data;
		newnode->_next = NULL;
		return newnode;
	}

}


void QueueInit(Queue* q) //初始化
{
	assert(q);

	q->_head = q->_tail = NULL;
}

void QueuePush(Queue* q, DataType data) //入队
{
	QueueNode *newnode = NULL;
	assert(q);

	newnode = BuyQueueNode(data);

	if (NULL == q->_head)     //如果队列为空
		q->_head = q->_tail = newnode;

	else
	{
		q->_tail->_next = newnode;  //先将新节点和队列连接起来
		q->_tail = newnode;         //将队列的尾更新
	}
}

void QueuePop(Queue* q) //出对
{
	QueueNode *del = NULL;
	assert(q);

	del = q->_head;
	q->_head = q->_head->_next;
	free(del);
}

DataType QueueFront(Queue* q) //取队头
{
	assert(q);
	//默认是有队列中是有数据的
	return q->_head->_data;
}

DataType QueueBack(Queue* q) //取队尾
{
	assert(q);
	//默认是有队列中是有数据的
	return q->_tail->_data;
}

void QueuePrint(Queue* q) //打印队列
{
	QueueNode *cur = NULL;
	assert(q);
	cur = q->_head;
	while (cur)
	{
		printf("%d ", cur->_data);
		cur = cur->_next;
	}
	printf("\n");
}

void QueueSize(Queue* q) //求队列中的数据个数
{	
	QueueNode *cur = NULL;
	int count = 0;
	assert(q);
	
	cur = q->_head;
	while (cur)
	{
		++count;
		cur = cur->_next;
	}
	printf("队列中的数据个数为:%d \n", count);
}

int EmptyQueue(Queue* q)//判断队列是否为空
{
	assert(q);

	if (NULL == q->_head)  //队列空返回0
		return 0;
	
	return 1;
}
#include"Queue.h"
#include"Stack.h"

//队列的测试///

//test()
//{
//	Queue q;
//	QueueInit(&q);
//
//	QueuePush(&q, 1);
//	QueuePush(&q, 2);
//	QueuePush(&q, 3);
//	QueuePush(&q, 4);
//	QueuePush(&q, 5);
//
//	QueueSize(&q);
//
//	QueuePrint(&q);
//
//	printf("队头为:%d \n", QueueFront(&q));
//	printf("队尾为:%d \n", QueueBack(&q));
//
//	QueuePop(&q);
//	QueuePop(&q);
//	QueuePop(&q);
//	QueuePop(&q);
//	//QueuePop(&q);
//
//	QueueSize(&q);
//
//	QueuePrint(&q);
//
//	printf("队头为:%d \n", QueueFront(&q));
//	printf("队尾为:%d \n", QueueBack(&q));
//
//}
//
//int main()
//{
//	test();
//
//	system("pause");
//	return 0;
//}

栈的测试//

//test()
//{
//	Stack s;
//	StackInit(&s);
//	StackPush(&s, 1);
//	StackPush(&s, 2);
//	StackPush(&s, 3);
//	StackPush(&s, 4);
//	StackPush(&s, 5);
//	StackPush(&s, 6);
//
//	StackSize(&s);
//	StackPrint(&s);
//	printf("%d \n",StackTop(&s));
//	//StackPop(&s);
//	StackPop(&s);
//	StackPop(&s);
//	StackPop(&s);
//	StackPop(&s);
//
//	StackSize(&s);
//
//	//StackPop(&s);
//	StackPrint(&s);
//}
//
//int main()
//{
//	test();
//
//	system("pause");
//	return 0;
//}

栈的应用测试///

测试括号匹配问题
//test1()
//{
//	char buf1[] = "(())abc{[(])}";  //左右括号次序不匹配
//	char buf2[] = "(()))abc{[]}";   //右括号多于左括号
//	char buf3[] = "(()()abc{[]}";   //左括号多于右括号
//	char buf4[] = "(())abc{[]()}";  //匹配正确
//
//	MatchBrackets(buf1, strlen(buf1));
//	MatchBrackets(buf2, strlen(buf2));
//	MatchBrackets(buf3, strlen(buf3));
//	MatchBrackets(buf4, strlen(buf4));
//}
//

//测试逆波兰表达式
test2()
{
	char rpn[] = "12 3 4 + * 6 - 8 2 / +";
	
	int ret = ExpressionRPN(rpn, strlen(rpn));
	printf("表达式结果为:%d\n", ret);
}


int main()
{
	//test1();
	test2();

	//char c[] = "12 3 4";
	//printf("%d\n", atoi(&c));

	system("pause");
	return 0;
}


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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值