数据结构--栈

1. 顺序栈 

Stack_Opreator.c

#include
#include
#include
#include

typedef bool status;
#define MAXSIZE 10
struct Stack{
    int stack[MAXSIZE];
    int top;
};

//创建顺序栈
struct Stack* Stack_Create(){
    struct Stack* p = (struct Stack*)malloc(sizeof(struct Stack));
    if(p==NULL){
        return NULL;
    }
    memset(p->stack,0,sizeof(p->stack));
    p->top = -1;//给初值
    return p;
}
status Stack_Push(struct Stack* p ,int data){
    //判断是否已经满了
    if(p->top==MAXSIZE-1){
        printf("栈已满,入栈失败\n");
        return false;
    }

    p->top+=1;
    p->stack[p->top] = data;
    return true;
}

//出栈
status Stack_Pop(struct Stack* p,int* data){
    //判断栈是否为空
	if(p->top==-1)
	{
		printf("栈为空栈,出栈失败!\n");
		return false;
	}

    *data = p->stack[p->top];
	p->stack[p->top]=0;//清空
    p->top--;
    return true;

}

//遍历栈
status Stack_travel(struct Stack* p){
    //判断是否为空
    int top_1 = p->top;

    if(top_1==-1){
        printf("栈为空\n");
        return false;
    }

    while(top_1>=0){
        printf("%d ",p->stack[top_1]);
        top_1--;
    }
    return true;

}

int main(){
    struct Stack* stack_ = Stack_Create();
    Stack_Push(stack_,10);
    Stack_Push(stack_,20);
	Stack_Push(stack_,30);
	Stack_travel(stack_);
	printf("\n******************\n");

    int data;
	Stack_Pop(stack_,&data);
	printf("取出的栈顶元素:%d\n",data);
	Stack_travel(stack_);

    return 0;    
}


2. 练习

Stack_Express_Get_Value.c

#include "stdio.h"
#include "stdlib.h"
#include "string.h"
#include "stdbool.h"
#define MAXSIZE_DATA 10
#define MAXSIZE_OPERATOR 10

//顺序栈表达式求值
struct Stack_Data
{
	int arr_data[MAXSIZE_DATA];
	int top;
};
struct Stack_Operator
{
	char arr_operator[MAXSIZE_OPERATOR];
	int top;
};

//栈的初始化
struct Stack_Data *Stack_Data_Init()//数字栈的创建
{
	struct Stack_Data *stack=(struct Stack_Data*)malloc(sizeof(struct Stack_Data));
	if(stack==NULL)
	{
		return NULL;
	}
	stack->top=-1;
	memset(stack->arr_data,0,sizeof(int)*MAXSIZE_DATA);
	return stack;
}
struct Stack_Operator*Stack_Operator_Init()//操作符栈的初始化
{
	struct Stack_Operator *stack=(struct Stack_Operator*)malloc(sizeof(struct Stack_Operator));
	if(stack==NULL)
	{
		return NULL;
	}
	stack->top=-1;
	memset(stack->arr_operator,0,MAXSIZE_OPERATOR);
	return stack;
}

//栈的遍历
bool Stack_Data_Travel(struct Stack_Data *P)
{
	if(P->top==-1)
	{
		return false;
	}
	printf("################数字栈的遍历################\n");
	while(P->top!=-1)
	{
		printf("data:%d\n",P->arr_data[P->top]);
		P->top--;
	}
	return true;
}

bool Stack_Operator_Travel(struct Stack_Operator *P)
{
	if(P->top==-1)
	{
		return false;
	}
	printf("################运算符栈的遍历################\n");
	while(P->top!=-1)
	{
		printf("operator:%c\n",P->arr_operator[P->top]);
		P->top--;
	}
	return true;
}


//栈判空
bool Stack_Data_IsEmpty(struct Stack_Data*P)
{
	if(P->top==-1)
	{
		return true;
	}
	return false;
}
bool Stack_Operator_IsEmpty(struct Stack_Operator *P)
{
	if(P->top==-1)
	{
		return true;
	}
	return false;
}
//入栈
bool Stack_Data_Push(struct Stack_Data *P,int data)
{
	if(P->top==MAXSIZE_DATA-1)
	{
		return false;
	}
	P->top++;
	P->arr_data[P->top]=data;
	return true;
}
bool Stack_Operator_Push(struct Stack_Operator *P,char operator)
{
	if(P->top==MAXSIZE_OPERATOR-1)
	{
		return false;
	}
	P->top++;
	P->arr_operator[P->top]=operator;
	return true;
}
//出栈
bool Stack_Data_Pop(struct Stack_Data *P,int *data)
{
	if(P->top==-1)
	{
		return false;
	}
	*data=P->arr_data[P->top];
	P->top--;
	return true;
}
bool Stack_Operator_Pop(struct Stack_Operator *P,char *operator)
{
	if(P->top==-1)
	{
		return false;
	}
	*operator=P->arr_operator[P->top];
	P->top--;
	return true;
}
//判断输入的是数字还是运算符, true:运算符, false:数字
char opt[5]={'+','-','*','/','#'};
bool is_opt(char ch)
{
	for(int i=0;i=opt2,则opt1出栈,opt2入栈,否则opt2入栈
char Priority(char opt1,char opt2)
{
	switch(opt1)
	{
		case '+':
			if(opt2=='+')
			{
				//opt1出栈,opt2入栈,取两个数字进行opt1运算,然后再入数字栈
				return '=';//优先级相等
			}
			else if(opt2=='-')
			{
				//opt1出栈,opt2入栈,取两个数字进行opt1运算,然后再入数字栈
				//优先级相等
				return '=';
			}
			else if(opt2=='*')
			{
				//opt2入栈
				return '<';
			}
			else if(opt2=='/')
			{
				//opt2入栈
				return '<';
			}
			break;
		case '-':
			if(opt2=='+')
			{
				//opt1出栈,opt2入栈,取两个数字进行opt1运算,然后再入数字栈
				return '=';//优先级相等
			}
			else if(opt2=='-')
			{
				//opt1出栈,opt2入栈,取两个数字进行opt1运算,然后再入数字栈
				//优先级相等
				return '=';
			}
			else if(opt2=='*')
			{
				//opt2入栈
				return '<';
			}
			else if(opt2=='/')
			{
				//opt2入栈
				return '<';
			}
			break;
		case '*':
			if(opt2=='+')
			{
				return '>';
			}
			else if(opt2=='-')
			{
				return '>';
			}
			else if(opt2=='*')
			{
				return '=';
			}
			else if(opt2=='/')
			{
				return '=';
			}
			break;
		case '/':
			if(opt2=='+')
			{
				return '>';
			}
			else if(opt2=='-')
			{
				return '>';
			}
			else if(opt2=='*')
			{
				return '=';
			}
			else if(opt2=='/')
			{
				return '=';
			}
			break;
		default:return '\0';break;//输入其他不符合法的字符返回为空
	}
}
int main()
{
	//表达式:5-4x3+5/2
	char express[]="5-4*3+5/2#";//可以加一个结束标志"#"
	struct Stack_Data *stack_data=Stack_Data_Init();
	struct Stack_Operator *stack_operator=Stack_Operator_Init();
	int data1;//每一次运算都会从数字栈中取两个数字出来
	int data2;
	for(int i=0;itop);
				printf("运算符栈顶指针:%d\n",stack_operator->top);
				while(stack_operator->top!=-1)
				{
					Stack_Data_Pop(stack_data,&data1);
					Stack_Data_Pop(stack_data,&data2);
					char yun;
					Stack_Operator_Pop(stack_operator,&yun);//取出栈顶操作符
					printf("出栈的字符:%c\n",stack_operator->arr_operator[stack_operator->top+1]);
					switch(yun)
					{
						case '+':Stack_Data_Push(stack_data,data2+data1);break;
						case '-':Stack_Data_Push(stack_data,data2-data1);break;
						case '*':Stack_Data_Push(stack_data,data2*data1);break;
						case '/':Stack_Data_Push(stack_data,data2/data1);break;
						default:break;
					}
				}
				break;
			}
			if(stack_operator->top==-1)
			{

				//表示是第一个运算符,进行入栈即可
				Stack_Operator_Push(stack_operator,express[i]);
				continue;//存入之后直接进入下一次循环,因为入栈了top++,如果不进入下一次循环就会进入else执行
			}	
			else //表示不是第一个运算符
			{
				//这时候需要判断该栈顶运算符与待入栈的运算符的优先级判断
				if(Priority(stack_operator->arr_operator[stack_operator->top],express[i])=='='||Priority(stack_operator->arr_operator[stack_operator->top],express[i])=='>')
				{
					//如果栈顶与运算符优先级与待入栈运算符优先级高或者等于,则出栈栈顶运算符,然后再入栈待入栈运算符
					char yun;
					Stack_Operator_Pop(stack_operator,&yun);
					switch(yun)
					{
						case '+'://加法运算
							//取数字栈中的两个数据进行运算,运算完将结果再入栈
							Stack_Data_Pop(stack_data,&data1);
							Stack_Data_Pop(stack_data,&data2);
							//将运算的结果,压入数字栈
							Stack_Data_Push(stack_data,data2+data1);
							//将待入栈的运算符进行入栈
							Stack_Operator_Push(stack_operator,express[i]);
							break;
						case '-'://减法运算
							//取数字栈中的两个数据进行运算,运算完将结果再入栈
							Stack_Data_Pop(stack_data,&data1);
							Stack_Data_Pop(stack_data,&data2);
							//将运算的结果,压入数字栈
							Stack_Data_Push(stack_data,data2-data1);
							//将待入栈的运算符进行入栈
							Stack_Operator_Push(stack_operator,express[i]);
						
							break;
						case '*'://乘法运算
							//取数字栈中的两个数据进行运算,运算完将结果再入栈
							Stack_Data_Pop(stack_data,&data1);
							Stack_Data_Pop(stack_data,&data2);
							//将运算的结果,压入数字栈
							Stack_Data_Push(stack_data,data2*data1);
							
							//再判断栈顶指针是否比待入栈的优先级高或者等于,如果优先级高或者等于则继续出栈,否则入栈
							while(Priority(stack_operator->arr_operator[stack_operator->top],express[i])=='='||Priority(stack_operator->arr_operator[stack_operator->top],express[i])=='>')
							{
								char yun;
								Stack_Operator_Pop(stack_operator,&yun);
								if(yun=='-')
								{
									Stack_Data_Pop(stack_data,&data1);
							                Stack_Data_Pop(stack_data,&data2);	
							                //将运算的结果,压入数字栈
							                Stack_Data_Push(stack_data,data2-data1);
								}
								if(stack_operator->top==-1)//直到运算符栈为空,才退出判断
								{
									break;
								}						
							}
							
							//将待入栈的运算符进行入栈
							Stack_Operator_Push(stack_operator,express[i]);

							break;
						case '/'://除法运算
							//取数字栈中的两个数据进行运算,运算完将结果再入栈
							Stack_Data_Pop(stack_data,&data1);
							Stack_Data_Pop(stack_data,&data2);
							//将运算的结果,压入数字栈
							Stack_Data_Push(stack_data,data2/data1);
							//将待入栈的运算符进行入栈
							Stack_Operator_Push(stack_operator,express[i]);
							break;
						defalut:break;
					}
				}
				else if(Priority(stack_operator->arr_operator[stack_operator->top],express[i])=='<')
				{
					//如果待入栈的运算符优先级大于栈顶优先级,则入栈
					Stack_Operator_Push(stack_operator,express[i]);
				}
			}
		}
		else
		{
			//如果是数字则入数字栈
			Stack_Data_Push(stack_data,express[i]-'0');
		}
	}
	printf("计算结果为:%d\n",stack_data->arr_data[stack_data->top]);
	return 0;
}



你可能感兴趣的:(数据结构,数据结构,linux,c语言,算法)