数据结构6:栈及其应用

1,栈的定义

栈是一种运算受限的线性表。限定仅在表尾进行插入和删除操作的线性表。这一端被称为栈顶,相对地,把另一端称为栈底。向一个栈插入新元素又称作进栈、入栈或压栈,它是把新元素放到栈顶元素的上面,使之成为新的栈顶元素;从一个栈删除元素又称作出栈或退栈,它是把栈顶元素删除掉,使其相邻的元素成为新的栈顶元素。

2.栈的基本操作

操作代码

1.定义

typedef struct Stack
{
	int top;
	int data[MAX_SIZE];
 } *StackPtr;

2.初始化

StackPtr initStack()
{
	StackPtr resultPtr = (StackPtr)malloc(sizeof(struct Stack));
	resultPtr->top = -1;
	return resultPtr;
 }

3.打印

void outputStack(StackPtr paraStack)
{
	for(int i=0;i<=paraStack->top;i++)
	{
		printf("%c ",paraStack->data[i]);
	}
	printf("\r\n");
 } 

4.入栈

//入栈
void push(StackPtr paraStackPtr,int paraValue)
{
	//判断是否栈满
	if(paraStackPtr->top >= MAX_SIZE)
	{
		printf("栈满,不能添加\r\n");
		return;
	 }
	paraStackPtr->top ++;
	paraStackPtr->data[paraStackPtr->top] = paraValue; 
}

5.出栈

char pop(StackPtr paraStackPtr)
{
	//判断空栈
	if(paraStackPtr->top < 0)
	{
		printf("空栈,不能删除\r\n");
		return '\0';
	 } 
	paraStackPtr->top --;
	return paraStackPtr->data[paraStackPtr->top + 1];
 }

6.提取栈顶 

//提取栈顶
int getTop(StackPtr paraStackPtr)
{
	//判断空栈
	if(paraStackPtr->top < 0)
	{
		printf("空栈,不能提取\r\n");
		return '\0';
	 } 
	return paraStackPtr->data[paraStackPtr->top];
} 

功能测试

void pushPopText()
{
	printf("栈进出测试开始:\r\n");
	//初始化
	StackPtr tempStack = initStack();
	printf("初始化后的栈:");
	outputStack(tempStack);
	//入栈
	for(char ch='a';ch<'n';ch++)
	{
		printf("添加%c:",ch);
		push(tempStack,ch);
		outputStack(tempStack);
	 } 
	//出栈
	for(int i=0;i<4;i++)
	{
		char ch=pop(tempStack);
		printf("删除%c:",ch);
		outputStack(tempStack);
	 } 
	printf("测试结束。\r\n");
	printf("\r\n"); 
 }

测试结果

栈进出测试开始:
初始化后的栈:
添加a:a
添加b:a b
添加c:a b c
添加d:a b c d
添加e:a b c d e
添加f:a b c d e f
添加g:a b c d e f g
添加h:a b c d e f g h
添加i:a b c d e f g h i
添加j:a b c d e f g h i j
添加k:a b c d e f g h i j k
添加l:栈满,不能添加
a b c d e f g h i j k
添加m:栈满,不能添加
a b c d e f g h i j k
删除k:a b c d e f g h i j
删除j:a b c d e f g h i
删除i:a b c d e f g h
删除h:a b c d e f g
测试结束。

3.括号匹配应用

操作代码

bool bracketMatch(char* paraString,int paraLength)//只有true和false两个返回值 
{
	//初始化,将#放入栈底
	StackPtr tempStack = initStack();
	push(tempStack,'#');
	
	char tempChar,tempPopedChar;
	for(int i=0;i<paraLength;i++)
	{
		tempChar = paraString[i];
		switch(tempChar)
		{
			case'(':
			case'[':
			case'{':
				push(tempStack,tempChar);
				break;
			case')':
				tempPopedChar = pop(tempStack);
				if(tempPopedChar != '(')
				{
					return false;
				}
				break;
			case']':
				tempPopedChar = pop(tempStack);
				if(tempPopedChar != '[')
				{
					return false;
				}
				break;
			case'}':
				tempPopedChar = pop(tempStack);
				if(tempPopedChar != '{')
				{
					return true;
				}
				break;
			default:
				break;
		}
	} 
	tempPopedChar = pop(tempStack);
	if(tempPopedChar != '#')
	{
		return false;
	}
	return true;
}

功能测试

void  bracketMatchText()
{
	printf("括号匹配测试开始:\r\n"); 
	char* tempExpression = "{7+2-[4+6*(7-3)]}/3";
	bool tempMatch = bracketMatch(tempExpression,17);
	printf("‘%s’是否括号匹配? %d\r\n",tempExpression,tempMatch);
	
	tempExpression = "[7-8*6)(]";
	tempMatch = bracketMatch(tempExpression,9);
	printf("‘%s’是否括号匹配? %d\r\n",tempExpression,tempMatch);
	
	tempExpression = "(()[])";
	tempMatch = bracketMatch(tempExpression,6);
	printf("‘%s’是否括号匹配? %d\r\n",tempExpression,tempMatch);
	
	tempExpression = "{]()";
	tempMatch = bracketMatch(tempExpression,4);
	printf("‘%s’是否括号匹配? %d\r\n",tempExpression,tempMatch);
	printf("测试结束。\r\n");
	printf("\r\n"); 
}

测试结果

括号匹配测试开始:
‘{7+2-[4+6*(7-3)]}/3’是否括号匹配? 1
‘[7-8*6)(]’是否括号匹配? 0
‘(()[])’是否括号匹配? 1
‘{]()’是否括号匹配? 0
测试结束。

4.多项式计算应用

C语言操作代码

//优先级关系(运用二维数组表示优先级关系,虽然代码繁琐,但是直观明了,不易出错) 
char priority(char ch1,char ch2)
{
	int i,j;
	char pri[7][7]={// +   -   *   /   (   )   = 
		             {'>','>','<','<','<','>','>'},  
                     {'>','>','<','<','<','>','>'},  
                     {'>','>','>','>','<','>','>'},  
                     {'>','>','>','>','<','>','>'},  
                     {'<','<','<','<','<','=','0'},  
                     {'>','>','>','>','0','>','>'},  
                     {'<','<','<','<','<','0','='}
					};
	switch(ch1)
	{
    	case '+': i = 0; 
			break;  
        case '-': i = 1; 
			break;  
        case '*': i = 2; 
			break;  
        case '/': i = 3; 
			break;  
        case '(': i = 4; 
			break;  
        case ')': i = 5; 
			break;
        case '=': i = 6; 
			break;
	}
	switch(ch2)
	{
    	case '+': j = 0; 
			break;  
        case '-': j = 1; 
			break;  
        case '*': j = 2; 
			break;  
        case '/': j = 3; 
			break;  
        case '(': j = 4; 
			break;  
        case ')': j = 5; 
			break;
        case '=': j = 6; 
			break;
    }
    return pri[i][j];
}

//计算
int evaluate(int a,char ch,int b)
{
	int result;
	switch(ch)
	{
		case'+':
			return a+b;
		case'-':
			return a-b;
		case'*':
			return a*b;
		case'/':
			if(b != 0)
				return a/b;
			else
			{
				printf("除数为0,无法计算\n");
			}
			
	}
}

//判断运算符和操作符
int judge(char ch)//运算符返回1,操作符返回0 
{
	switch(ch)
	{
		case'+':   
        case'-':  
        case'*':   
        case'/':   
        case'(':   
        case')': 
        case'=': 
            return 1;
		 default:
		    return 0;
	}
 } 
 
//多项式计算
int evaluateExpression(char *paraExpression)
{
	StackPtr tempStack1=initStack();//运算数栈
	StackPtr tempStack2=initStack();//运算符栈 
	int a,b,ch,x,x1,x2;//x存放多余出栈元素,x1,x2用于计算
	char cha;
	int i = 0;
	push(tempStack2,'=');//多项式以'='结尾 
	cha = paraExpression[i++];
	while(cha != '=' || getTop(tempStack2) != '=')
	{
		if(judge(cha))//判断是否为运算符 
		{
			switch(priority(getTop(tempStack2),cha))
			{
				case'<':
					push(tempStack2,cha);
					cha = paraExpression[i++];
					break;
				case'>':
					ch = pop(tempStack2);
					b = pop(tempStack1);
					a = pop(tempStack1);
					push(tempStack1,evaluate(a,ch,b));
					break;
				case'=':
					x = pop(tempStack2);
					cha = paraExpression[i++];
					break;
			}
		 }
		 else if(isdigit(cha))
		 {
		 	x1 = cha-'0';
		 	push(tempStack1,x1);
		 	x2 = x1;
		 	cha = paraExpression[i++];
		 	while(isdigit(cha))判断是否为运算数,是则返回1(存储于ctype.h头文件中)
		 	{
		 		x1 = cha - '0';
		 		x2 = 10*x2 + x1;
		 		x = pop(tempStack1);
		 		push(tempStack1,x2);
		 		cha = paraExpression[i++];
			 }
		 } 
		else if(cha == ' ')
		{
			while(cha == ' ')
			{
				cha == paraExpression[i++];
			}
		}
		else
		{
			printf("多项式错误\n");
		}
	 }
	return getTop(tempStack1);
 } 

功能测试

void evaluateExpressionText()
{
	printf("多项式计算测试开始:\n");
	int result;
	char *tempExpression="7-6*8/2=";
	result = evaluateExpression(tempExpression);
	printf("%s%d\n",tempExpression,result);
	
	tempExpression="3+6*9=";
	result = evaluateExpression(tempExpression);
	printf("%s%d\n",tempExpression,result);
	
	tempExpression="7*(4+2)-(3*5)=";
	result = evaluateExpression(tempExpression);
	printf("%s%d\n",tempExpression,result);
	printf("测试结束。\n");
 } 

测试结果

多项式计算测试开始:
7-6*8/2=-17
3+6*9=57
7*(4+2)-(3*5)=27
测试结束。

总代码

#include <stdio.h>
#include <malloc.h>
#include <ctype.h>
#define MAX_SIZE 10

//定义
typedef struct Stack
{
	int top;
	int data[MAX_SIZE];
 } *StackPtr;

//初始化
StackPtr initStack()
{
	StackPtr resultPtr = (StackPtr)malloc(sizeof(struct Stack));
	resultPtr->top = -1;
	return resultPtr;
 }

//打印
void outputStack(StackPtr paraStack)
{
	for(int i=0;i<=paraStack->top;i++)
	{
		printf("%c ",paraStack->data[i]);
	}
	printf("\r\n");
 } 

//入栈
void push(StackPtr paraStackPtr,int paraValue)
{
	//判断是否栈满
	if(paraStackPtr->top >= MAX_SIZE)
	{
		printf("栈满,不能添加\r\n");
		return;
	 }
	paraStackPtr->top ++;
	paraStackPtr->data[paraStackPtr->top] = paraValue; 
}

//出栈
char pop(StackPtr paraStackPtr)
{
	//判断空栈
	if(paraStackPtr->top < 0)
	{
		printf("空栈,不能删除\r\n");
		return '\0';
	 } 
	paraStackPtr->top --;
	return paraStackPtr->data[paraStackPtr->top + 1];
 }


//提取栈顶
int getTop(StackPtr paraStackPtr)
{
	//判断空栈
	if(paraStackPtr->top < 0)
	{
		printf("空栈,不能提取\r\n");
		return '\0';
	 } 
	return paraStackPtr->data[paraStackPtr->top];
} 

//应用一:括号匹配
bool bracketMatch(char* paraString,int paraLength)//只有true和false两个返回值 
{
	//初始化,将#放入栈底
	StackPtr tempStack = initStack();
	push(tempStack,'#');
	
	char tempChar,tempPopedChar;
	for(int i=0;i<paraLength;i++)
	{
		tempChar = paraString[i];
		switch(tempChar)
		{
			case'(':
			case'[':
			case'{':
				push(tempStack,tempChar);
				break;
			case')':
				tempPopedChar = pop(tempStack);
				if(tempPopedChar != '(')
				{
					return false;
				}
				break;
			case']':
				tempPopedChar = pop(tempStack);
				if(tempPopedChar != '[')
				{
					return false;
				}
				break;
			case'}':
				tempPopedChar = pop(tempStack);
				if(tempPopedChar != '{')
				{
					return true;
				}
				break;
			default:
				break;
		}
	} 
	tempPopedChar = pop(tempStack);
	if(tempPopedChar != '#')
	{
		return false;
	}
	return true;
}

 //应用二:多项式的计算
//优先级关系(运用二维数组表示优先级关系,虽然代码繁琐,但是直观明了,不易出错) 
char priority(char ch1,char ch2)
{
	int i,j;
	char pri[7][7]={// +   -   *   /   (   )   = 
		             {'>','>','<','<','<','>','>'},  
                     {'>','>','<','<','<','>','>'},  
                     {'>','>','>','>','<','>','>'},  
                     {'>','>','>','>','<','>','>'},  
                     {'<','<','<','<','<','=','0'},  
                     {'>','>','>','>','0','>','>'},  
                     {'<','<','<','<','<','0','='}
					};
	switch(ch1)
	{
    	case '+': i = 0; 
			break;  
        case '-': i = 1; 
			break;  
        case '*': i = 2; 
			break;  
        case '/': i = 3; 
			break;  
        case '(': i = 4; 
			break;  
        case ')': i = 5; 
			break;
        case '=': i = 6; 
			break;
	}
	switch(ch2)
	{
    	case '+': j = 0; 
			break;  
        case '-': j = 1; 
			break;  
        case '*': j = 2; 
			break;  
        case '/': j = 3; 
			break;  
        case '(': j = 4; 
			break;  
        case ')': j = 5; 
			break;
        case '=': j = 6; 
			break;
    }
    return pri[i][j];
}

//计算
int evaluate(int a,char ch,int b)
{
	int result;
	switch(ch)
	{
		case'+':
			return a+b;
		case'-':
			return a-b;
		case'*':
			return a*b;
		case'/':
			if(b != 0)
				return a/b;
			else
			{
				printf("除数为0,无法计算\n");
			}
			
	}
}

//判断运算符和操作符
int judge(char ch)//运算符返回1,操作符返回0 
{
	switch(ch)
	{
		case'+':   
        case'-':  
        case'*':   
        case'/':   
        case'(':   
        case')': 
        case'=': 
            return 1;
		 default:
		    return 0;
	}
 } 
 
//多项式计算
int evaluateExpression(char *paraExpression)
{
	StackPtr tempStack1=initStack();//运算数栈
	StackPtr tempStack2=initStack();//运算符栈 
	int a,b,ch,x,x1,x2;//x存放多余出栈元素,x1,x2用于计算
	char cha;
	int i = 0;
	push(tempStack2,'=');//多项式以'='结尾 
	cha = paraExpression[i++];
	while(cha != '=' || getTop(tempStack2) != '=')
	{
		if(judge(cha))//判断是否为运算符 
		{
			switch(priority(getTop(tempStack2),cha))
			{
				case'<':
					push(tempStack2,cha);
					cha = paraExpression[i++];
					break;
				case'>':
					ch = pop(tempStack2);
					b = pop(tempStack1);
					a = pop(tempStack1);
					push(tempStack1,evaluate(a,ch,b));
					break;
				case'=':
					x = pop(tempStack2);
					cha = paraExpression[i++];
					break;
			}
		 }
		 else if(isdigit(cha))
		 {
		 	x1 = cha-'0';
		 	push(tempStack1,x1);
		 	x2 = x1;
		 	cha = paraExpression[i++];
		 	while(isdigit(cha))//判断是否为运算数,是则返回1(存储于ctype.h头文件中)
		 	{
		 		x1 = cha - '0';
		 		x2 = 10*x2 + x1;
		 		x = pop(tempStack1);
		 		push(tempStack1,x2);
		 		cha = paraExpression[i++];
			 }
		 } 
		else if(cha == ' ')
		{
			while(cha == ' ')
			{
				cha == paraExpression[i++];
			}
		}
		else
		{
			printf("多项式错误\n");
		}
	 }
	return getTop(tempStack1);
 } 

//栈的进出测试
void pushPopText()
{
	printf("栈进出测试开始:\r\n");
	//初始化
	StackPtr tempStack = initStack();
	printf("初始化后的栈:");
	outputStack(tempStack);
	//入栈
	for(char ch='a';ch<'n';ch++)
	{
		printf("添加%c:",ch);
		push(tempStack,ch);
		outputStack(tempStack);
	 } 
	//出栈
	for(int i=0;i<4;i++)
	{
		char ch=pop(tempStack);
		printf("删除%c:",ch);
		outputStack(tempStack);
	 } 
	printf("测试结束。\r\n");
	printf("\r\n"); 
 }

//括号匹配测试
void  bracketMatchText()
{
	printf("括号匹配测试开始:\r\n"); 
	char* tempExpression = "{7+2-[4+6*(7-3)]}/3";
	bool tempMatch = bracketMatch(tempExpression,17);
	printf("‘%s’是否括号匹配? %d\r\n",tempExpression,tempMatch);
	
	tempExpression = "[7-8*6)(]";
	tempMatch = bracketMatch(tempExpression,9);
	printf("‘%s’是否括号匹配? %d\r\n",tempExpression,tempMatch);
	
	tempExpression = "(()[])";
	tempMatch = bracketMatch(tempExpression,6);
	printf("‘%s’是否括号匹配? %d\r\n",tempExpression,tempMatch);
	
	tempExpression = "{]()";
	tempMatch = bracketMatch(tempExpression,4);
	printf("‘%s’是否括号匹配? %d\r\n",tempExpression,tempMatch);
	printf("测试结束。\r\n");
	printf("\r\n"); 
}

//多项式计算测试
void evaluateExpressionText()
{
	printf("多项式计算测试开始:\n");
	int result;
	char *tempExpression="7-6*8/2=";
	result = evaluateExpression(tempExpression);
	printf("%s%d\n",tempExpression,result);
	
	tempExpression="3+6*9=";
	result = evaluateExpression(tempExpression);
	printf("%s%d\n",tempExpression,result);
	
	tempExpression="7*(4+2)-(3*5)=";
	result = evaluateExpression(tempExpression);
	printf("%s%d\n",tempExpression,result);
	printf("测试结束。\n");
 } 

int main()
{
	pushPopText();
	bracketMatchText();
	evaluateExpressionText(); 
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值