数据结构_栈

栈的定义

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
这里有个思想,函数执行得怎么样了用返回值表示,真正要返回的东西放在参数列表里(用传入引用的方式实现返回)

栈的实现

在这里插入图片描述


Tool.h
#pragma once
enum Error_Type
{
	Success,Overflow, Underflow
};
enum Ret_Type
{
	Str,Num,End
};


Stack.h

#pragma once
#include"iostream"
#include"tool.h"//存的是Error_Type
using namespace std;
/*
enum Error_Type
{
	Success, Overflow, Underflow
};
*/
template <class T1>
class Stack
{public:
	virtual bool isempty() = 0 ;//是否为空
	virtual Error_Type pop(T1& ret)=0;//出栈
	virtual Error_Type push(const T1 &input) = 0;//入栈
	virtual Error_Type get_Top(T1& ret) = 0;//获取栈顶元素
	
};


数组实现

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

Stack_arr.h

#pragma once
#include "Stack.h"
template<class T1>
class Stack_arr :
    public Stack<T1>//存的东西
{
public:
    int get_Count()const;//获取栈中元素个数
    Stack_arr();//构造函数
    bool isfull()const;//栈是否已满
    T1 data_arr[28]{0};//存数据的数组
    bool isempty()  ;
    Error_Type pop(T1& ret) ;
    Error_Type push(const T1& input) ;
    Error_Type get_Top(T1& ret) ;

private:
    int count;
    int top;
};



template<class T1>
bool
Stack_arr<T1>::isempty()
{
	if (count == 0)return 1;//空的返回1
	else return 0;//非空返回0
}
template<class T1>
int
Stack_arr<T1>::get_Count()const//获取栈中数据个数
{
	return count;
}
template<class T1>
Stack_arr<T1>::Stack_arr()
{
	count = 0;
	top = 0;

}
template<class T1>
bool
Stack_arr<T1>::isfull()const
{
	if (count == 28)return 1;//满了返回1
	else return 0;
}
template<class T1>
Error_Type
Stack_arr<T1>::pop(T1& ret)
{
	if (count == 0)//栈为空则打印信息,返回下溢错误类型
	{
		cout << "栈已空无法出栈" << endl;
		return Underflow;
	}
	else//非空则计数,栈顶调整,并输出被pop的东西,返回Success
	{
		count--;
		top--;
		ret = data_arr[top];
		return Success;
	}
}
template<class T1>
Error_Type
Stack_arr<T1>::push(const T1& input)
{
	if (count == 28)//满了就打印信息返回上溢错误
	{
		cout << "栈已满无法入栈" << endl;
		return Overflow;
	}
	else//没满就计数增加,top后移,返回成功
	{
		count++;
		data_arr[top] = input;
		top++;

		return Success;
	}
}
template<class T1>
Error_Type
Stack_arr<T1>::get_Top(T1& ret)
{
	if (count == 0)
	{
		cout << "栈为空!" << endl;
		return Underflow;
	}
	else
	{
		ret = data_arr[top - 1];
		return Success;
	}
}

链实现

在这里插入图片描述

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述


Stack_node.h

#pragma once
#include "Stack.h"
template<class T1>
class Stack_node :
    public Stack<T1>//存的东西
{
public:
    
    Stack_node();
    class Node
    {
    public:
        T1 data;
        Node* next;
    };
    Node* top;
    bool isempty()  ;
    Error_Type pop(T1& ret) ;
    Error_Type push(const T1& input) ;
    Error_Type get_Top(T1& ret) ;

private:
    int count;
};



template<class T1>
bool
Stack_node<T1>::isempty()//栈是否为空
{
	if (top == NULL)return 1;
	else return 0;
}
template<class T1>
Stack_node<T1>::Stack_node()//初始化
{
	count = 0;
	top = NULL;

}
template<class T1>
Error_Type
Stack_node<T1>::get_Top(T1& ret)//取栈顶元素
{
	if (count == 0)
	{
		cout << "栈是空的!" << endl;
		return Underflow;
	}
	else
	{
		ret = top->data;
		return Success;
	}
}
template<class T1>
Error_Type
Stack_node<T1>::push(const T1& input)//入栈
{
	auto node = new Node;
	node->data = input;
	node->next = top;
	top = node;
	count++;
	return Success;
}
template<class T1>
Error_Type
Stack_node<T1>::pop(T1& ret)//出栈
{
	if (count == 0)
	{
		cout << "栈已空!" << endl;
		return Underflow;
	}
	else
	{
		ret = top->data;
		auto top_tem = top;
		top = top->next;
		delete top_tem;
		count--;
		return Success;
	}

}

栈的应用

计算器(顺便完成括号配对)

理论:

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

代码:

Calc.h

#pragma once
#include"Stack_node.h"
#include<String>
class Calc
{
public:
	bool execute();//执行函数
	Ret_Type get_Str_Num(char &str, double &num);//逐个提取数字和字符
	bool doCalc(double& ret);//计算
	bool doCheckParentheses();//检查括号配对
	string input;//存输入的算式
	double doEachTypeCalc(char sign, double num1, double num2);//进行数字的加减乘除运算
	int n = 0;
};
bool
Calc::execute()//执行函数
{
	double ret;
	cout<<"请输入算式,注意括号要配对"<<endl;
	cin >> input;
	
	//检查括号
a:	if (doCheckParentheses())
	{
		//运算
		doCalc(ret);
		cout << "结果是" << ret <<endl;
		return 1;
	}
	else
	{
		cout<<"请重新输入"<<endl;
		cin >> input;
		goto a;
	}
}
Ret_Type 
Calc::get_Str_Num(char& str, double& num)
{
	double ret_num = 0;
	
	if ('0' <= input[n] && input[n] <= '9')//对数字进行处理
	{
		while ('0' <= input[n] && input[n] <= '9')
		{
			ret_num = ret_num * 10 + input[n] - '0';
			n++;
		}
		num = ret_num;
		return Num;
	}
	else if (input[n] != '\0')//对符号进行处理
	{
		ret_num = 0;
		n++;
		str = input[n-1];
		return Str;
	}
	else//结束
		return End;

}
bool
Calc::doCheckParentheses()
{
	Stack_node<char> stack;
	int n = 0;
	char tmp;
	while (input[n]!='\0')
	{
		if (input[n] == '(')stack.push(input[n]);//遇到(入栈
		else if (input[n] == ')')//遇到)先判断栈是否为空再出栈
		{
			if (stack.isempty())
				return 0;
			else
			{
				stack.pop(tmp);
			}
		}
		n++;

	}
	//cout<<"能出来吗?"<<endl;
	if (!stack.isempty())return 0;//有没配对左括号,返回false
	else return 1;
}
double 
Calc::doEachTypeCalc(char sign, double num1, double num2)
{
	switch (sign)
	{case'+':
		return num1 + num2;
	case'-':
		return num1 - num2;
	case'*':
		return num1 * num2;
	case'/':
		return num1 / num2;
	}

}
bool
Calc::doCalc(double& ret)
{
	double num,test;//接收读取到的数字,找bug
	char str;//接收读取到的符号
	char str_tmp;//存从栈中取出的符号
	double num_calc1,num_calc2;//用于存计算的两个数字
	Stack_node<char> stack_char;//字符栈
	Stack_node<double> stack_num;//数字栈
	Ret_Type rettype;
	while ( (rettype=get_Str_Num(str, num))!=End)
	{
		if (rettype == Str)//读取到字符
		{
			if (stack_char.isempty())stack_char.push(str);//若符号栈为空直接入栈
			else
			{
				switch (str)
				{
				case '+':case'-'://加减法
					if (stack_char.get_Top(str_tmp) == Success)//读取栈顶符号
					{
						if (str_tmp != '(')//不是括号就把它进行运算,再放入新进的符号
						{

							//计算后把结果入栈
							stack_num.pop(num_calc2);
							stack_num.pop(num_calc1);
							stack_num.push(doEachTypeCalc(str_tmp, num_calc1, num_calc2));
							//stack_num.get_Top(test);
							//cout<<test<<endl;
							stack_char.pop(str_tmp);//算完后出栈,这里str_tmp无意义
							stack_char.push(str);
						}
						else//是括号就入栈
							stack_char.push(str);
					}

						break;
				
				case '/':
					
				case '*':
					if (stack_char.get_Top(str_tmp) == Success)//读取栈顶符号
					{
						if (str_tmp != '('&& str_tmp != '+'&& str_tmp != '-')//不是括号就把它进行运算,再放入新进的符号
						{

							//计算后把结果入栈
							stack_num.pop(num_calc2);
							stack_num.pop(num_calc1);
							stack_num.push(doEachTypeCalc(str_tmp, num_calc1, num_calc2));
							//stack_num.get_Top(test);
							//cout << test << endl;
							stack_char.pop(str_tmp);//算完后出栈,这里str_tmp无意义
							stack_char.push(str);
						}
						else//是括号,加减号就入栈
							stack_char.push(str);
					}


					break;
				case '(':
					stack_char.push('(');
					break;
				case')':
					while (stack_char.get_Top(str_tmp)==Success&&str_tmp != '(')//符号栈一直出栈,直到遇到(为止
					{
						stack_num.pop(num_calc2);
						stack_num.pop(num_calc1);
						stack_num.push(doEachTypeCalc(str_tmp, num_calc1, num_calc2));
						stack_char.pop(str_tmp);
					}
					stack_char.pop(str_tmp);//(出栈
					break;
				}
			}

		}
		else if (rettype == Num)//读取到数字
		{
			stack_num.push(num);//直接入栈
		}
		else//结束后返回true
		{
			return 1;
		}
	}
	while (!stack_char.isempty())
	{
		stack_char.get_Top(str_tmp);
		stack_num.pop(num_calc2);
		stack_num.pop(num_calc1);
		stack_num.push(doEachTypeCalc(str_tmp, num_calc1, num_calc2));
		//stack_num.get_Top(test);
		//cout << test << endl;
		stack_char.pop(str_tmp);//算完后出栈,这里str_tmp无意义
	}
	stack_num.get_Top(ret);
	return 1;
		 

火车调度问题(合法序列检查)

练习

在这里插入图片描述
在这里插入图片描述
上面的策略一有误,“比他们都小“改为比max后面的数都小

代码

在这里插入图片描述

就展示CheckLegalSequence.h和源.cpp,其他上次展示过了
CheckLegalSequence.h


#pragma once
#include"Stack_node.h"
#include<String>
class CheckLegalSequence
{
public:
	bool execute();
	bool checkIntegrity();//数据完整性检查
	bool strategy_Normal();//常规方式检查
	bool stratepy_Stack();//用栈检查
private:
	string input;//输入的序列
};
bool CheckLegalSequence::execute()
{
	cout<<"请输入序列,由大于0的整数组成的个位数"<<endl;
	cin >> input;
	//cout << input.length();
	if (!checkIntegrity())
	{
		cout<<"不是合法序列,有数字缺失或重复"<<endl;
		return 0;
	}
	else
	{
		if (!stratepy_Stack())
		{
			cout << "不是合法序列(用stack查出)" << endl;
		}
		if (!strategy_Normal())
		{
			cout << "不是合法序列(用其他方法查出)" << endl;
			return 0;
		}
		
	}
	cout<<"是合法序列"<<endl;
	return 1;

}
bool CheckLegalSequence::checkIntegrity()
{
	int n = 0,length=0;
	for (n = 0; n < input.length(); n++)
	{
		if (input[n] - '0' > length)length = input[n] - '0';
	}
	if (length != input.length())return 0;
	int* check = new int[length]{0};
	for (n = 0; n < input.length(); n++)
	{
		check[input[n]-'1'] = 1;
	}
	for (n = 0; n < input.length(); n++)
	{
		if (check[n] == 0)return 0;
	}
	return 1;
}
bool CheckLegalSequence::strategy_Normal()
{
	int min = 0, max = 0, n;
	for (n = 1; n < input.length(); n++)
	{
		if (input[min] > input[n])min = n;
		else if (input[max] < input[n])
{
min=n;
max = n;
}
		else
		{
			return 0;
		}
	}
	return 1;
}
bool CheckLegalSequence::stratepy_Stack()
{
	Stack_node<int> stack;
	int n = 0,inttmp,n_input=0;
	for (n = 0; n < input.length(); n++)
	{
		if (input[n_input]-'0' != n + 1)//不相等就入栈
		{
			stack.push(n + 1);

		}
		else
		{
			n_input++;//相等就去看下一个,然后把栈里的能出的出掉
			while (!stack.isempty()&&stack.get_Top(inttmp)==Success&& inttmp == input[n_input] - '0')
			{
				
				n_input++;
				stack.pop(inttmp);
			}
		}
	}
	if (!stack.isempty())return 0;
	return 1;
}.cpp
#include"CheckLegalSequence.h"
int main()
{
	CheckLegalSequence().execute();
	return 0;
}

代替递归(后面递归会介绍,这里简单提一下)

1.	用栈代替递归来完成快速排序
代码:
#include<iostream>
using namespace std;
struct shuju
{
	int a;
	int b;

};
template<class T>
class stack
{
public:
	stack() {};
	stack(T b) :shu(b) {}

	T shu;
	stack* next = NULL;
	T pop();
	void push(T b);
	T top();
	bool isempty();

	void bianli();
};
template<class T>
stack<T>* ptop = NULL;

template<class T>
T stack<T>::pop()
{
	T b;
	stack* gj1 = ptop<T>;
	b = ptop<T>->shu;
	ptop<T> = ptop<T>->next;
	delete gj1;



	return b;
}
template<class T>
void stack<T>::push(T b)
{
	stack* gj1 = new stack(b);
	gj1->next = ptop<T>;

	ptop<T> = gj1;
}
template<class T>
T stack<T>::top()
{
	return ptop->shu;
}
template<class T>
bool stack<T>::isempty()
{
	if (ptop<T> == NULL)
		return 0;
	else return 1;
}
template<class T>
void stack<T>::bianli()
{
	stack* gj1 = ptop;
	while (gj1 != NULL)
	{
		cout << gj1->shu << "  ";
		gj1 = gj1->next;
	}
	cout << endl;
}
int sort(int* a, int b, int c);
int main()
{
	int a[128] = { 0 }, i = 0, n = 0, l = 0, g = 0, m = 0, first, end;
	stack<shuju> li;
	cout << "请输入需要排序的数据" << endl;
	while (cin >> a[i]) { i++; n++; }
	g = n - 1;
	l = 0;
	shuju t, gj1;
	t.a = l;
	t.b = g;
	li.push(t);
	while (li.isempty())
	{
		
		gj1 = li.pop();
		first = gj1.a;
		end = gj1.b;
		m = sort(a, first, end);
		sort(a, first, end);
		if (first - m > 1)
		{
			gj1.b = m - 1;
			li.push(gj1);
		}
		if (end - m > 1)
		{
			gj1.a = m + 1;
			li.push(gj1);
		}
		
	}
	for (i = 0; i < n; i++)
	{
		cout << a[i] << "  ";
	}
	return 0;
}
int sort(int* a, int b, int c)
{
	
	int p = a[b];
	while (c > b)
	{
		
		while (a[c] > p)
		{
			c--;
		}
		a[b] = a[c];
		while (a[b] < p)
		{
			b++;
		}
		a[c] = a[b];
		
	}
	a[c] = p;
	return c;
}

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值