算法與數據結構(9): 棧

在這裏插入圖片描述

注:轉載請標明原文出處鏈接:https://xiongyiming.blog.csdn.net/article/details/100828853


1 棧簡介

棧 (stack) 又名堆棧,它是一種運算受限的線性表。限定僅在表尾進行插入和刪除操作的線性表。這一端被稱爲棧頂,相對地,把另一端稱爲棧底。向一個棧插入新元素又稱作進棧、入棧或壓棧,它是把新元素放到棧頂元素的上面,使之成爲新的棧頂元素;從一個棧刪除元素又稱作出棧或退棧,它是把棧頂元素刪除掉,使其相鄰的元素成爲新的棧頂元素。
(以上均來自百度百科)


棧機制性質:後進先出

在這裏插入圖片描述



2 單一數據類型棧

代碼示例

要求

棧類
目的:掌握棧的實現原理和運行機制

  1. MyStack(int size) //分配內存初始化棧空間,設定棧容量,棧頂
  2. ~MyStack() //回收站空間內存
  3. bool stackEmpty() //判定棧是否爲空,爲空返回true,非空返回false
  4. bool stackFull() //判定棧是否已滿,爲滿返回true,非滿返回false
  5. void clearStack() //清空棧
  6. int stackLength() //已有元素的個數
  7. bool push(char elem) //元素入棧,棧頂上升
  8. bool pop(char &elem) //元素出棧,棧頂下降
  9. void stackTraverse() //遍歷元素中所有元素

MyStack.h

#pragma once

class MyStack
{
public:
	MyStack(int size); //分配內存初始化棧空間,設定棧容量,棧頂
	~MyStack();        //回收站空間內存
	bool stackEmpty(); //判定棧是否爲空,爲空返回true,非空返回false
	bool stackFull();  //判定棧是否已滿,爲滿返回true,非滿返回false
	void clearStack(); //清空棧
	int stackLength(); //已有元素的個數
	bool push(char elem); //元素入棧,棧頂上升
	bool pop(char &elem); //元素出棧,棧頂下降
	void stackTraverse(bool isFromButtom); //遍歷元素中所有元素

private:
	char *m_pBuffer;//棧空間指針
	int m_iSize;//棧容量
	int m_iTop;//棧頂,棧中元素個數

};

MyStack.cpp

#include<iostream>
#include"MyStack.h"

using namespace std;

//分配內存初始化棧空間,設定棧容量,棧頂
MyStack::MyStack(int size)
{
	m_iSize = size;
	m_pBuffer = new char[size];
	m_iTop = 0;
}

//回收站空間內存
MyStack::~MyStack()
{
	delete[]m_pBuffer;
}

//判定棧是否爲空,爲空返回true,非空返回false
bool MyStack::stackEmpty()
{
	if (0 == m_iTop)
	{
		return true;
	}
	else
	{
		return false;
	}
}

//判定棧是否已滿,爲滿返回true,非滿返回false
bool MyStack::stackFull()
{
	if (m_iTop == m_iSize)
	{
		return true;
	}
	else
	{
		return false;
	}
}



//清空棧
void MyStack::clearStack()
{
	m_iTop = 0;
}


//已有元素的個數
int MyStack::stackLength()
{
	return m_iTop;
}


//元素入棧,棧頂上升
bool MyStack::push(char elem)
{
	if (stackFull())
	{
		return false;
	}
	m_pBuffer[m_iTop] = elem;
	m_iTop++;

	return true;
}

//元素出棧,棧頂下降
bool MyStack::pop(char &elem)
{
	if (stackEmpty())
	{
		return false;
	}
	m_iTop--;
	elem = m_pBuffer[m_iTop];
	
	return true;
}


//遍歷元素中所有元素
void MyStack::stackTraverse(bool isFromButtom)
{
	if (isFromButtom)
	{
		for (int i = 0; i < m_iTop; i++)
		{
			cout << m_pBuffer[i] << ",";
		}
	}
	
	else
	{
		for (int i = m_iTop - 1; i >= 0; i--)
		{
			cout << m_pBuffer[i] << ",";
		}
	}

}

main.cpp

#include<iostream>
#include"MyStack.h"

using namespace std;


/*************************************************************************

棧類
目的:掌握棧的實現原理和運行機制
	MyStack(int size) //分配內存初始化棧空間,設定棧容量,棧頂
	~MyStack()        //回收站空間內存
	bool stackEmpty() //判定棧是否爲空,爲空返回true,非空返回false
	bool stackFull()  //判定棧是否已滿,爲滿返回true,非滿返回false
	void clearStack() //清空棧
	int stackLength() //已有元素的個數
	bool push(char elem) //元素入棧,棧頂上升
	bool pop(char &elem) //元素出棧,棧頂下降
	void stackTraverse() //遍歷元素中所有元素
**************************************************************************/


int main(void)
{
	MyStack *pStack = new MyStack(5);

	if (pStack->stackEmpty())
	{
		cout << "棧爲空" << endl;
	}

	cout << "------------------" << endl;
	if (pStack->stackFull())
	{
		cout << "棧爲滿" << endl;
	}
	cout << "棧長度=" << pStack->stackLength() << endl;

	//入棧
	pStack->push('a');//低
	pStack->push('b');
	pStack->push('c');
	pStack->push('d');
	pStack->push('e');//頂
	if (pStack->stackEmpty())
	{
		cout << "棧爲空" << endl;
	}

	cout << "------------------" << endl;
	if (pStack->stackFull())
	{
		cout << "棧爲滿" << endl;
	}
	cout << "棧長度=" << pStack->stackLength() << endl;

	cout << "------------------" << endl;
	
	//遍歷
	pStack->stackTraverse(true);
	cout << endl;
	cout << "------------------" << endl;

	//出棧
	char elem = 0;
	pStack->pop(elem);
	//遍歷
	pStack->stackTraverse(false);
cout << endl;



	delete pStack;
	pStack = NULL;

	cin.get();
	return 0;
}

運行結果

在這裏插入圖片描述



3 棧模板

(1) 案例改造

棧類
目的:靈活掌握棧的運行機制,理解抽象數據類型在棧中的應用
1 定義Coordinate類
2 改造棧類,使其可以適用於座標類

Coordinate.h

#pragma once
class Coordinate
{
public:
	Coordinate(int x=0, int y=0);
	void printCoordinate();

private:
	int m_iX;
	int m_iY;

};

Coordinate.cpp

#include<iostream>
#include"Coordinate.h"

using namespace std;

Coordinate::Coordinate(int x, int y)
{
	m_iX = x;
	m_iY = y;
}


void Coordinate::printCoordinate()
{
	cout << "(" << m_iX << "," << m_iY << ")" << endl;
}

MyStack.h

#pragma once
#include"Coordinate.h"
class MyStack
{
public:
	MyStack(int size); //分配內存初始化棧空間,設定棧容量,棧頂
	~MyStack();        //回收站空間內存
	bool stackEmpty(); //判定棧是否爲空,爲空返回true,非空返回false
	bool stackFull();  //判定棧是否已滿,爲滿返回true,非滿返回false
	void clearStack(); //清空棧
	int stackLength(); //已有元素的個數
	bool push(Coordinate elem); //元素入棧,棧頂上升
	bool pop(Coordinate &elem); //元素出棧,棧頂下降
	void stackTraverse(bool isFromButtom); //遍歷元素中所有元素

private:
	Coordinate *m_pBuffer;//棧空間指針
	int m_iSize;//棧容量
	int m_iTop;//棧頂,棧中元素個數

};

MyStack.cpp

#include<iostream>
#include"MyStack.h"

using namespace std;

//分配內存初始化棧空間,設定棧容量,棧頂
MyStack::MyStack(int size)
{
	m_iSize = size;
	m_pBuffer = new Coordinate[size];
	m_iTop = 0;
}

//回收站空間內存
MyStack::~MyStack()
{
	delete[]m_pBuffer;
}

//判定棧是否爲空,爲空返回true,非空返回false
bool MyStack::stackEmpty()
{
	if (0 == m_iTop)
	{
		return true;
	}
	else
	{
		return false;
	}
}

//判定棧是否已滿,爲滿返回true,非滿返回false
bool MyStack::stackFull()
{
	if (m_iTop == m_iSize)
	{
		return true;
	}
	else
	{
		return false;
	}
}



//清空棧
void MyStack::clearStack()
{
	m_iTop = 0;
}


//已有元素的個數
int MyStack::stackLength()
{
	return m_iTop;
}


//元素入棧,棧頂上升
bool MyStack::push(Coordinate elem)
{
	if (stackFull())
	{
		return false;
	}
	m_pBuffer[m_iTop] = elem;
	m_iTop++;

	return true;
}

//元素出棧,棧頂下降
bool MyStack::pop(Coordinate &elem)
{
	if (stackEmpty())
	{
		return false;
	}
	m_iTop--;
	elem = m_pBuffer[m_iTop];
	
	return true;
}


//遍歷元素中所有元素
void MyStack::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();
		}
	}

}

main.cpp

#include<iostream>
#include"MyStack.h"

using namespace std;


/*************************************************************************

棧類
目的:靈活掌握棧的運行機制,理解抽象數據類型在棧中的應用
1 定義Coordinate類
2 改造棧類,使其可以適用於座標類
**************************************************************************/


int main(void)
{
	MyStack *pStack = new MyStack(5);

	//入棧
	pStack->push(Coordinate(1, 2));//低
	pStack->push(Coordinate(3, 4));//頂

	pStack->stackTraverse(true);
	cout << "-------------------" << endl;
	pStack->stackTraverse(false);
	cout << "-------------------" << endl;

	cout << "棧長度" << pStack->stackLength() << endl;


	delete pStack;
	pStack = NULL;

	cin.get();
	return 0;
}

運行結果

在這裏插入圖片描述



(2) 案例改造——棧模板

棧 類模板
目的:靈活掌握棧的運行機制,理解抽象數據類型在棧中的應用
將普通棧改造爲類模板棧,使其可以通過用於任何數據類型

MyStack.h

#pragma once
#include"Coordinate.h"
template<typename T>
class MyStack
{
public:
	MyStack(int size); //分配內存初始化棧空間,設定棧容量,棧頂
	~MyStack();        //回收站空間內存
	bool stackEmpty(); //判定棧是否爲空,爲空返回true,非空返回false
	bool stackFull();  //判定棧是否已滿,爲滿返回true,非滿返回false
	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>
//判定棧是否爲空,爲空返回true,非空返回false
bool MyStack<T>::stackEmpty()
{
	if (0 == m_iTop)
	{
		return true;
	}
	else
	{
		return false;
	}
}


template<typename T>
//判定棧是否已滿,爲滿返回true,非滿返回false
bool MyStack<T>::stackFull()
{
	if (m_iTop == m_iSize)
	{
		return true;
	}
	else
	{
		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;
	}
	m_pBuffer[m_iTop] = elem;
	m_iTop++;

	return true;
}


template<typename T>
//元素出棧,棧頂下降
bool MyStack<T>::pop(T &elem)
{
	if (stackEmpty())
	{
		return false;
	}
	m_iTop--;
	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];

		}
	}

	else
	{
		for (int i = m_iTop - 1; i >= 0; i--)
		{
			cout << m_pBuffer[i];

		}
	}

}

Coordinate.h

#pragma once
#include<iostream>
using namespace std;

class Coordinate
{

	friend ostream &operator<<(ostream &out, Coordinate &coor);//運算符重載聲明

public:
	Coordinate(int x=0, int y=0);
	void printCoordinate();

private:
	int m_iX;
	int m_iY;

};

Coordinate.cpp

#include<iostream>
#include"Coordinate.h"

using namespace std;

Coordinate::Coordinate(int x, int y)
{
	m_iX = x;
	m_iY = y;
}


void Coordinate::printCoordinate()
{
	cout << "(" << m_iX << "," << m_iY << ")" << endl;
}

//運算符重載定義
ostream &operator<<(ostream &out, Coordinate &coor)
{
	out << "(" << coor.m_iX << "," << coor.m_iY << ")" << endl;
	
	return out;
}

main.cpp

#include<iostream>
#include"MyStack.h"
#include"Coordinate.h"
using namespace std;


/*************************************************************************

棧 類模板
目的:靈活掌握棧的運行機制,理解抽象數據類型在棧中的應用
	將普通棧改造爲類模板棧,使其可以通過用於任何數據類型
**************************************************************************/


int main(void)
{
	MyStack<Coordinate> *pStack = new MyStack<Coordinate>(5);

	//入棧
	pStack->push(Coordinate(1, 2));//低
	pStack->push(Coordinate(3, 4));//頂

	pStack->stackTraverse(true);
	cout << "-------------------" << endl;
	pStack->stackTraverse(false);
	cout << "-------------------" << endl;

	cout << "棧長度" << pStack->stackLength() << endl;


	delete pStack;
	pStack = NULL;

	cin.get();
	return 0;
}

運行結果

在這裏插入圖片描述



參考資料

[1] 數據結構探險—棧篇

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章