数据结构C代码——栈以及应用

栈的实现可以用指针和数组来实现,也可以用脚标作指针的功能。这里我们先用脚标来实现。

定义结构体:

typedef struct CharStack{
	int top;//栈顶的脚标
	int data[STACK_MAX_SIZE];//用于存储数据的空间
}*CharStackPtr;

栈的初始化

CharStackPtr charStackInit(){
	CharStackPtr tempStack = (CharStackPtr)malloc(sizeof(struct CharStack));
	tempStack->top = -1;//表示栈为空
	
	return tempStack;
}

链表的打印:

这儿在写的时候犯了个小错误(用 top--;来输出—),应该用i来记录top,否则栈在输出的时候就被我们清空了

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

 栈的输入输出

void push(CharStackPtr paraStack,int paraChar ){
	if(paraStack->top >= STACK_MAX_SIZE-1){
		printf("没有位置,不能再插入\r\n"); 
		return;
	}//判断栈是否满
	paraStack->top ++;
	printf("%d ",paraStack->top);
	paraStack->data[paraStack->top] = paraChar;
}

char pop(CharStackPtr paraStack){
	if(paraStack->top >= 0){
		paraStack->top--;//指向下一个值
		return paraStack->data[paraStack->top+1];//原本处理值
	}else{
		printf("栈为空\r\n");
		return '\0'; 
	}
}

完整代码

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

#define STACK_MAX_SIZE 10

typedef struct CharStack{
	int top;
	int data[STACK_MAX_SIZE];
}*CharStackPtr;

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

CharStackPtr charStackInit(){
	CharStackPtr tempStack = (CharStackPtr)malloc(sizeof( CharStack));
	tempStack->top = -1;
	
	return tempStack;
}

void push(CharStackPtr paraStack,int paraChar ){
	if(paraStack->top >= STACK_MAX_SIZE-1){
		printf("没有位置,不能再插入\r\n"); 
		return;
	}
	paraStack->top ++;
	printf("%d ",paraStack->top);
	paraStack->data[paraStack->top] = paraChar;
}

char pop(CharStackPtr paraStack){
	if(paraStack->top >= 0){
		paraStack->top--;
		return paraStack->data[paraStack->top+1];
	}else{
		printf("栈为空\r\n");
		return '\0'; 
	}
}

void pushPopTest() {
    printf("---- pushPopTest begins. ----\r\n");

    CharStackPtr tempStack = charStackInit();
    printf("After initialization, the stack is: ");
	outputStack(tempStack);

	char ch;
	for (ch = 'a'; ch < 'm'; ch ++) {
		printf("Pushing %c.\r\n", ch);
		push(tempStack, ch);
		outputStack(tempStack);
	}
	
	for (int i = 0; i < 3; i ++) {
		ch = pop(tempStack);
		if(ch){
			printf("Pop %c.\r\n", ch);
		}
		outputStack(tempStack);
	}

    printf("---- pushPopTest ends. ----\r\n");
}
int main() {
	pushPopTest();
}

 


 栈的应用——括号匹配及计算多项式

如 {[()]}为正确,{[}]错误,这儿的括号匹配融入进计算多项式中,由于这里二者融合了就只做了()的判断,在学习多项式计算要多自己手动画图,跟着逻辑走,才能更好的理解与掌握。

这里我采用了两个栈,一个栈存储数据,一个用于存储运算符,边读边计算,读到两个连续的运算符号的第二个时(由于这里涉及到两个运算符,有一个必定是存储于栈中),先不必慌着进栈,先判断两者优先级,若前者优先级高或者两者优先级相等,则优先级高的运算符弹出栈,存储数据的栈弹出两个数据用于计算,再将优先级低的存进栈中;若后者更高则直接存储。当整个计算式读完之后,存储运算符的不为空则继续进行计算,直到存储运算符的栈中运算符全部弹出(计算时读完以后,尽管边读边计算,依旧会存在没有计算的情况)。具体理解请画图跟踪;

完整代码

#include <stdio.h>
#include <malloc.h>
#include <string.h> 
#define Max 1000

typedef struct CharStack{
	int top;
	int data[Max];
}*CharStackPtr;//定义结构体 

CharStackPtr CharStackInit(){
	CharStackPtr tempStack = (CharStackPtr)malloc(sizeof(struct CharStack));
	tempStack->top = 0;
	tempStack->data[tempStack->top] = '#';
	
	return tempStack;
}//栈的初始化 

void output(CharStackPtr paraStack){
	printf("计算结果是%d",paraStack->data[paraStack->top]);
}

void push(CharStackPtr paraStackPtr,int paraValue){
	if(paraStackPtr->top >= Max-1){
		printf("栈已满,不能再输入\r\n");
		return; 
	}//判断栈是否满了 
	paraStackPtr->top++;
	paraStackPtr->data[paraStackPtr->top] = paraValue; 
}// 栈的初始化 

char popChar(CharStackPtr paraStackPtr){
	if(paraStackPtr->data[paraStackPtr->top]=='#'){
		return '\0'; 
	}else{
		paraStackPtr->top--;
		return paraStackPtr->data[paraStackPtr->top+1];
	}
}//用于弹出栈的运算符 

int popNum(CharStackPtr paraStackPtr){
	if(paraStackPtr->data[paraStackPtr->top]=='#'){
		return '\0'; 
	}else{
		paraStackPtr->top--;
		return paraStackPtr->data[paraStackPtr->top+1];
	}
}//弹出栈中的运算数字 

int eval(CharStackPtr paraStackPtr,CharStackPtr paraNumPtr){
	int a = popNum(paraNumPtr);
	int b = popNum(paraNumPtr);
	char c = popChar(paraStackPtr);
	int x;
	if(c == '+') x = a+b;
	else if(c == '-') x = b-a;
	else if(c == '*') x = a*b;
	else x = b/a;
	push(paraNumPtr,x);	
}//对数字进行计算 

bool checkput(CharStackPtr paraStackPtr){
	if(popChar(paraStackPtr)=='('){
		return true;
	}else{
		return false;
	}
}//判断括号输入是否正确 
int JudgeFirst(char s){
	if(s=='+'||s=='-') return 1;
	else return 2;
}//设计运算优先级 


int main(){
	while(1) {
		char str[Max];
		scanf("%s",&str);
		int i=0,j;
		CharStackPtr num = CharStackInit();//该栈用于存储数据 
		CharStackPtr ch1= CharStackInit(); //该栈用于存储运算符 
		CharStackPtr ch2= CharStackInit(); //用于存储括号,方便判断括号输入是否匹配 
		j=strlen(str);
		for(i=0;i<j;i++){
			char c = str[i];
			if('0'<=c && c<= '9'){
				int x = 0,j = i;
				while(j<strlen(str) && ('0'<=str[j]&& str[j]<='9')){
					x = x*10+str[j]-'0';
					j++;
				}
				i = j-1;
				push(num,x);
			}//读取数据 
			 else if(c =='('){
				push (ch1,c);
				push (ch2,c);
			}
			else if(c==')'){	
				if(checkput(ch2) == 0){
					printf("输入错误,请检查括号是否匹配\r\n");
					popChar(ch2);
				}else{
					while(ch1->data[ch1->top]!='(')eval(ch1,num);
					popChar(ch1);
				}
			}else{
				
				while(ch1->top!=0&&ch1->data[ch1->top] != '('&& (JudgeFirst(ch1->data[ch1->top])>=JudgeFirst(str[i]))){
					eval(ch1,num);
				}
				push(ch1,c);
			}//存储运算符,并在一定条件下进行计算 
		}
		while(ch1->data[ch1->top]!='#') eval(ch1,num);
		
		//判断括号输入的正确性 
		if(ch2->data[ch2->top]!='#'){
			printf("输入错误,请检查括号是否匹配\r\n");
			return 0;
		}else{
			output(num);
		}
	}
}

测试结果

 

 

 

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值