对象的集合 -- 栈,使用stl 中的vector 或者 原始数组来实现

1.栈的性质:后进先出(LIFO),只能从栈顶删除(pop)或添加元素(push)。


2.栈的实现:

实现一个栈主要是实现push(下压) pop(弹出) 两个操作,数据结构我们选择用STL 的 vector 或 原始数组。


i.利用STL 的vector 我们可以容易地实现一个栈,而不用去考虑关于vector实现的细节。

具体实现如下:


stack.h

#ifndef STACK_H
#define STACK_H

#include <vector>

template<class T>

class MyStack
{
public:
	MyStack();
	~MyStack();
	void push(T item);
	T pop();
	bool isEmpty();
	int size();
private:
	std::vector<T>* myStackVectorPointer;
	int sizeOfStack;
};

#endif

stack.cpp

#include "stack.h"

template <class T>
MyStack<T>::MyStack() : sizeOfStack(0)
{
	myStackVectorPointer = new std::vector<T>();
}

template <class T>
MyStack<T>::~MyStack(){}

template <class T>
void MyStack<T>::push(T item)
{
	myStackVectorPointer->push_back(item); //直接利用push_back函数来完成push操作
	++sizeOfStack;
}

template <class T>
T MyStack<T>::pop()
{
	if (sizeOfStack == 0)
	{
		return NULL;
	}
	else 
	{
		return myStackVectorPointer->at(--sizeOfStack);
	}
}

template <class T>
bool MyStack<T>::isEmpty()
{
	return sizeOfStack == 0;
}


main.cpp

#include <iostream>
#include <string>
#include "stack.h"
#include "stack.cpp"

using namespace std;

int main(int argc, char** argv)
{
	MyStack<double> myStack;
	for (int i = 0; i != 10; ++i)
	{
		myStack.push(i + 0.5);
	}

	double result = 0;
	while (!myStack.isEmpty())
	{
		result += myStack.pop();
	}
	cout << result << endl;return 0;

}


ii.使用原始数组来实现:


stack.h

#ifndef STACK_H
#define STACK_H

#include <vector>
#include <iostream>

using namespace std;

template<class T>

class MyStack
{
public:
	MyStack();
	~MyStack();
	void push(T item);
	T pop();
	bool isEmpty();
	int size();
private:
	void resize(int size);
	int sizeOfStack;       //栈的大小
	int currentStackTop; 	//当前栈顶的位置
	T* pointerOfStackArray;   //内置数据结构数组的首地址
};

#endif


stack.cpp:

#include "stack.h"

template <class T>
MyStack<T>::MyStack() : sizeOfStack(0),currentStackTop(0)
{
	pointerOfStackArray = new T[1];      //在堆上面分配一个长度为1的数组
}

template <class T>
MyStack<T>::~MyStack(){}

template <class T>
void MyStack<T>::push(T item)
{
	if (isEmpty())              //如果当前栈为空,那么就把栈的长度设置为2
	{
		resize(2);
	}

	//如果栈已经满了,那么就要动态调整栈的大小,把栈大小设置为当前的两倍。
	else if (sizeOfStack == currentStackTop)      
	{
		resize(sizeOfStack * 2); 
	}

	pointerOfStackArray[currentStackTop++] = item;
}

template <class T>
T MyStack<T>::pop()
{
	if (isEmpty())          //判空,如果在空栈上面进行pop操作的话,那么输出提示,并结束调用。
	{
		cout << "The Stack Is Empty" << endl;
		return NULL;
	}

	T currentItem = pointerOfStackArray[--currentStackTop];

	//如果pop之后,栈内的元素小于等于栈大小的四分之1,那么就把栈的大小缩短为当前的二分之1。
	if (currentStackTop <= sizeOfStack / 4)     
	{
		resize(sizeOfStack / 2);
	}
	return currentItem;
}


//调整栈大小的函数,在堆上面重新分配一个数组,复制元素,最后修改类里面的数组的首地址。
template <class T>
void MyStack<T>::resize(int size)      
{
	T* currentArray = new T[size];
	for (int i = 0; i != sizeOfStack; ++i)
	{
		currentArray[i] = pointerOfStackArray[i];
	}

	pointerOfStackArray = currentArray;
	sizeOfStack = size;
}

//判空函数。
template <class T>
bool MyStack<T>::isEmpty()
{
	return currentStackTop == 0;
}


main.cpp:

#include <iostream>
#include <string>
#include "stack.h"
#include "stack.cpp"


int main(int argc, char** argv)
{
	MyStack<string> myStack;
	for (int i = 0; i != 10; ++i)
	{
		myStack.push(std::to_string(i) + 'a');
	}

	while (!myStack.isEmpty())
	{
		cout << myStack.pop() << "  ";
	}
	cout << endl;

	return 0;
}

3.总结:

对于这两种实现方式,都是使用了数组来作为内部的数据结构,并且无论是vector 或者自己写的原始数组,在数组满的时候,和数组元素较小的时候,都要动态地调整数组的大小,调用相应的函数(vector的自增长和原始数组的重新分配空间并移动元素 resize() )对于栈这种数据结构,关心的只是当前栈顶的元素(只对栈顶元素进行操作),所以我们可以使用另外的数据结构来当作栈的内置数据结构 --链表。

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值