算法与数据结构基础-栈

栈是一种特殊的线性表,只允许在表的一端进行插入或者删除操作。有栈顶(top)和栈底(bottom),无数据时叫空栈,插入(push)操作称“进栈“,”压栈”,删除(pop)操作称“退栈”,”出栈“
栈机制 后进先出(LIFO)
栈要素 栈底(为0),栈顶(出入栈被处理的)
存储结构
顺序存储(顺序栈):地址连续的存储单元依次存放自栈底到栈顶,栈底不变,栈顶移动。
链式存储(链式栈):由节点构成的单链表实现,插入和删除操作只能在链表头进行。无头节点的单链表,无栈满问题,可扩充。

栈实现

template<typename T>
class MyStack
{
public:
	MyStack(int szie);		//分配内存初始化栈空间,设定栈容量,栈顶
	~MyStack();				//回收栈空间内存
	bool stackEmpty();		//判定栈是否为空
	bool stackFull();		//判定栈是否为满
	void clearStack();		//清空栈
	int stackLength();		//已有元素的个数
	bool push(T elem);	//元素入栈,栈顶上升
	bool pop(T &elem);	//元素出栈,栈顶下降
	void stackTraverse(bool isFromButtom);	//遍历栈中所有元素

private:
	T *m_pBuffer;		//栈空间指针,类型要与数据的类型一致
	int m_iSize;			//栈容量
	int m_iTop;				//栈顶,栈中元素个数
};
template<typename T>
MyStack<T>::MyStack(int size){
	m_iSize = size;
	m_pBuffer = new T[size];
	m_iTop = 0;
}

template<typename T>
MyStack<T>::~MyStack(){
	delete[]m_pBuffer;
}

template<typename T>
bool MyStack<T>::stackEmpty(){
	if (m_iTop == 0)	//if(0==m_iTop)漏写=系统会报错
		return true;
	else
		return false;
}

template<typename T>
bool MyStack<T>::stackFull(){
	if (m_iTop >= m_iSize)
		return true;
	return false;
}

template<typename T>
void MyStack<T>::clearStack(){
	m_iTop = 0;
}

template<typename T>
int MyStack<T>::stackLength(){
	return m_iTop;
}

template<typename T>
bool MyStack<T>::push(T elem){
	if (stackFull())
		return false;			//或者可以throw抛异常,throw 1;
	m_pBuffer[m_iTop++] = elem;//m_iTop指向的总是下一位(空位)
	return true;
}

template<typename T>
bool MyStack<T>::pop(T &elem){	//main里申请该类型的变量,传入参数引用来得到栈顶元素值
	if (stackEmpty())
		return false;
	elem = m_pBuffer[--m_iTop];//栈顶先减,才能去到元素
	return true;
}

template<typename T>
void MyStack<T>::stackTraverse(bool isFromButtom){	//由参数控制遍历方式
	if (isFromButtom){			//从栈底开始
		for (int i = 0; i < m_iTop; i++){
			cout << m_pBuffer[i]<<" ";
			//m_pBuffer[i].printCoordinate();//当数据类型为对象,使用对象的输出函。使用模板类时,对象要做输出运算符重载
		}
	}
	else{						//从栈顶开始
		for (int i = m_iTop - 1; i >= 0; i--){
			cout << m_pBuffer[i];
			//m_pBuffer[i].printCoordinate();
		}
	}
}

应用

MyStack<int> *pStack=new MyStack<int>(5);//指定数据类型
MyStack<Coordinate> *pStack=new MyStack<Coordinate>(5);

栈用于进制转换

char num[]="0123456789abcdef";//十六进制的下标索引

MyStack<int> *pStack=new MyStack<int>(20);
int N,mod=0;
cin<<N;
while(N!=0){
	mod=N%2;//8,16
	pStack->push(mod);//从栈顶插入余数
	N/=2;
}
//pStack->stackTraverse(false);从栈顶遍历,16进制不可用

int element=0;
while(!pStack->stackEmpty()){
	pStack->pop(element);
	cout<<num[element];//出栈元素作为索引
}

delete pStack;
pStack=NULL;
return 0;

括号匹配

	MyStack<char> *pStack = new MyStack<char>(30);//存放用于匹配的元素

	MyStack<char> *pNeedStack = new MyStack<char>(30);//存放需要匹配的元素

	char str[] = "[[()]]";

	char currentNeed = 0;

	for (int i = 0; i<strlen(str); i++){
		if (str[i] != currentNeed){
			pStack->push(str[i]);
			switch (str[i]){
			case '[':
				if (currentNeed != 0){		//如果当前需要的已有,先入栈
					pNeedStack->push(currentNeed);
				}
				currentNeed = ']';
					break;
			case '(':
				if (currentNeed != 0){
					pNeedStack->push(currentNeed);
				}
				currentNeed = ')';
				break;
			default:
				cout << "字符串括号不匹配" << endl;//避免因后方多括号而未入栈(栈已经空了)的情况
				return 0;

			}
		}
		else{			//匹配成功
			char elem;
			pStack->pop(elem);
			if (!pNeedStack->pop(currentNeed)){
				currentNeed = 0;
			}
		}
	}
	if (pStack->stackEmpty()){
		cout << "字符串括号匹配" << endl;
	}
	else{
		cout << "字符串括号不匹配" << endl;
	}

	delete pStack;
	pStack = NULL;
	delete pNeedStack;
	pNeedStack = NULL;

你可能感兴趣的:(笔记,数据结构,算法)