数据结构之栈的使用

简介- 栈stack

栈(stack)是限定仅在表尾进行插入或删除操作的线性表。

LIFO: Last In First Out 后进先出  表

“思想”:先进后出,后进先出

栈顶 top: 允许插入和删除操作的那一端,我们称之为栈顶
栈尾(栈底, bottom):

1. 顺序栈

特征:栈中各个元素在物理上(内存)上相邻的。

typedef int ElemType;
#define MAX_LEN 1000

struct SeqStack
{
	ElemType Elem[MAX_LEN];
	int top; //指示栈顶元素的下标
	//top == -1, 表示空栈

};

2. 链式栈

特征:栈中各个元素在物理上(内存)上不必相邻

typedef int ElemType;

struct node
{
	ElemType data;
	struct node *next;
	struct node *prev;
};

struct LinkedStack
{
	int length; //栈中元素个数
	struct node *bottom; //指向栈底结点,first
	struct node *top; //指向栈顶结点,last
};

栈的操作

InitStack
DestroyStack
ClearStack
StackEmpty
StackLength
GetTop
Pop
Push

代码实现

1. 顺序栈

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

typedef int ElemType;
#define MAX_LEN 1000

struct SeqStack
{
	ElemType Elem[MAX_LEN];
	int top; //指示栈顶元素的下标
	//top == -1, 表示空栈

};

//初始化一个顺序栈
struct SeqStack* InitStack()
{
	struct SeqStack *s = malloc(sizeof(*s));

	s->top = -1; // 表示空栈

	return s;
}

//销毁一个顺序栈
void DestroyStack(struct SeqStack *s)
{
	if (s)
	{
		free(s);
	}
}

//清空一个顺序栈

void ClearStack(struct SeqStack *s)
{
	s->top = -1; //清空了
}

/*
	判断栈是否为空,如果为空返回1,
	否则返回0
*/
int StackEmpty(struct SeqStack *s)
{
	return s->top == -1 ;
}


//返回栈中元素的个数
int StackLength(struct SeqStack *s)
{
	return s->top  + 1;
}


//返回栈顶元素,但不出栈
ElemType GetTop(struct SeqStack*s)
{
	return s->Elem[s->top];
}


//出栈
ElemType Pop(struct SeqStack *s)
{
	ElemType e = s->Elem[s->top];

	s->top--;

	return e;
}

//进栈
void Push(struct SeqStack *s, ElemType x)
{
	s->Elem[++s->top] = x;
}

//判断运算符 ch1 的优先级是否比ch2要高
//如果要高则返回1,否则返回0
int compare_prior(char ch1, char ch2)
{

	if ((ch1 == '*' || ch1 == '/' || ch1 == '%') 
		&& (ch2 == '+' || ch2 == '-'))
	{
		return 1;
	}

	return 0;
}

int calucate(int a , char ch, int b)
{
	switch(ch)
	{
		case '+':
			return a + b;
		case '-':
			return a - b;
		case '*':
			return a * b;
		case '/':
			return a / b;
		case '%':
			return a % b;
		default:
			//error
			break;
	}
}


int is_operator(char ch)
{
	if (ch == '+' || ch =='-' || ch == '*' || ch =='/' || ch == '%')
		return 1;

	return 0;
}

int execulate(char *str)
{
	struct SeqStack *op = InitStack(); //操作数的栈
	struct SeqStack *ch = InitStack(); //运算符的栈

	while (*str)
	{
	
		//迎接一个操作数,如果是操作数则入栈
		if (*str >= '0' && *str <= '9')
		{
			//取操作数
			int s = 0;
			while (*str >= '0' && *str <= '9')
			{
				s = s * 10 + (*str - '0');
				str++;
			}

			//操作数入栈
			Push(op, s);
		}
		

		//迎接一个运算符
		if (is_operator(*str))
		{
			while (1)
			{
				/*运算符栈为空 ||  我比栈顶元素优级要高*/
				if (StackEmpty(ch) || compare_prior(*str, GetTop(ch)))
				{
					//入栈
					Push(ch, *str);
					break;
				}
				else
				{
					//取运算符栈顶元素出来运算
					int a; //第一个操作数
					int b; //第二个操作数
					char c;//运算符, + - * / %

					b = Pop(op);
					a = Pop(op);
					c = Pop(ch);
					
					Push(op, calucate(a, c, b) );
				}
			}
		
		}
		//
		str++;
	}

	//如果运算符栈不为空,则取出运算
	while (!StackEmpty(ch))
	{
		//取运算符栈顶元素出来运算
		int a; //第一个操作数
		int b; //第二个操作数
		char c;//运算符, + - * / %

		b = Pop(op);
		a = Pop(op);
		c = Pop(ch);
		
		Push(op, calucate(a, c, b) );
	}

	return Pop(op);
}

int main()
{
	char expr[1000];
	gets(expr);

	//printf("%s %d\n",expr, strlen(expr));

	printf("%s = %d\n", expr, execulate(expr));

}

2. 链式栈

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

typedef int ElemType;

struct node
{
	ElemType data;
	struct node *next;
	struct node *prev;
};

struct LinkedStack
{
	int length; //栈中元素个数
	struct node *bottom; //指向栈底结点,first
	struct node *top; //指向栈顶结点,last
};


//初始化一个链式栈
struct LinkedStack* InitStack()
{
	struct LinkedStack*s = malloc(sizeof(*s));

	s->bottom = s->top = NULL;
	s->length = 0;
}


//清空栈
void  ClearStack(struct LinkedStack *s)
{
	struct node *p = s->top;
	struct node *pre;

	while(p)
	{
		pre = p->prev;

		pre->next = NULL;
		p->prev = NULL;

		free(p);

		p = pre;
	}

	s->bottom = s->top = NULL;
	s->length = 0;

}

//销毁一个链式栈
void DestroyStack(struct LinkedStack * s)
{
	
	ClearStack(s);
	free(s);
	
}

//判断栈是否为空,如果为空,则返回1,
//否则返回0
int StackEmpty(struct LinkedStack *s)
{
	return s->length == 0;
}

//返回链式栈中元素的个数
int StackLength(struct LinkedStack * s)
{
	return s->length;
}


//返回栈顶元素,但不出栈
ElemType GetTop(struct LinkedStack *s )
{
	ElemType e = s->top->data;

	return e;
}

//出栈
ElemType Pop(struct LinkedStack *s )
{
	ElemType e = s->top->data;

	struct node *p = s->top;

	s->top = p->prev;

	s->top->next = NULL;
	p->prev = NULL;

	s->length--;
	free(p);

	return e;
}

//进栈
void Push(struct LinkedStack*s, ElemType e)
{
	struct node *p = malloc(sizeof(*p));
	p->data = e;
	p->next = p->prev = NULL;

	if (s->top == NULL)
	{
		s->top = s->bottom = p;
	}
	else
	{
		s->top->next = p;
		p->prev = s->top;

		s->top = p;
	}

	s->length++;
}


int main()
{
	struct LinkedStack *stack = InitStack();
	Push(stack, 100);
	Push(stack, 200);
	Push(stack, 300);
	Push(stack, 400);
	Push(stack, 500);
	printf("data1=%d\n", Pop(stack));
	printf("data2=%d\n", Pop(stack));
	printf("data3=%d\n", Pop(stack));
	printf("data4=%d\n", Pop(stack));
	printf("data5=%d\n", Pop(stack));
}
  • 1
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

路过的小熊~

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值