特殊线性表(一)栈的C++实现

栈的限定是仅在表尾进行插入和删除操作的线性表.允许插入和删除的一端称为栈顶,另一端称为栈底。栈具有后进先出的特性.栈的实现同样有顺序栈和链栈两种。

1)顺序栈:

栈的顺序实现比较简单,这里我们讨论一种两栈共享栈空间的顺序栈,它可以避免两个栈时,一个栈满,而另一个栈还有大量存储空间的情况.

#define  MAX_SIZE 1024
template <class T>
class CBothStack
{
private:
	T m_array[MAX_SIZE];
	int m_top1;
	int m_top2;
public:
	CBothStack();
	~CBothStack(){}
	void Push(int i, T value);
	T Pop(int i);
	bool Empty(int i);
	T GetTop(int i);
	void PrintStack();
};

template <class T>
CBothStack<T>::CBothStack()
{
	m_top1 = -1;
	m_top2 = MAX_SIZE;
}

template <class T>
void CBothStack<T>::Push(int i, T value)
{
	// 判断栈是否已满
	if((m_top2 - m_top1) == 1)
	{
		throw "栈满";
	}
	if (i == 1)
	{
		m_array[++m_top1] = value;
	}else
	{
		m_array[--m_top2] = value;
	}
}

template<class T>
T CBothStack<T>::Pop(int i)
{
	if (i == 1)
	{
		if (m_top1 == - 1)
		{
			throw "栈1没有元素";
		}
		T value = m_array[m_top1--];
		return value;
	}else
	{
		if (m_top2 == MAX_SIZE)
		{
			throw "栈2没有元素";
		}
		T value = m_array[m_top2++];
		return value;
	}
}

template <class T>
T CBothStack<T>::GetTop(int i)
{
	if (i == 1)
	{
		if (m_top1 == - 1)
		{
			throw "栈1没有元素";
		}
		T value = m_array[m_top1];
		return value;
	}else
	{
		if (m_top2 == MAX_SIZE)
		{
			throw "栈2没有元素";
		}
		T value = m_array[m_top2];
		return value;
	}
}

template <class T>
bool CBothStack<T>::Empty(int i)
{
	if (i == 1)
	{
		return (m_top1 == -1 ? true : false);
	}else
	{
		return (m_top2 == MAX_SIZE ? true : false);
	}
}

template<class T>
void CBothStack<T>::PrintStack()
{
	if (!Empty(1))
	{
		printf("栈1:");
		int top = m_top1;
		while (top >= 0)
		{
			printf("%d, ", m_array[top--]);
		}
	}
	if (!Empty(2))
	{
		printf("栈2:");
		int top = m_top2;
		while (top < MAX_SIZE)
		{
			printf("%d, ", m_array[top++]);
		}
	}
}
2)链栈的实现:

链栈的操作实际上是单链表操作的简化,插入和删除只需要考虑栈顶第一个位置元素的情况.

template <class T>
struct Node
{
	Node* pNextNode;
	T m_value;
};
template <class T>
class CLinkStack
{
private:
	Node<T>* m_top;
public:
	CLinkStack();
	~CLinkStack();
	void Push(T value);
	T Pop();
	bool Empty();
	T GetTop();
};

template <class T>
CLinkStack<T>::CLinkStack()
{
	m_top = NULL;
}

template <class T>
CLinkStack<T>::~CLinkStack()
{
	if (m_top != NULL)
	{
		Node<T>* s = m_top;
		while (s != NULL)
		{
			printf("1,");
			Node<T>* r = s;
			s = s->pNextNode;
			delete r;
		}
	}
	m_top = NULL;
}

template <class T>
void CLinkStack<T>::Push(T value)
{
	Node<T>* s = new Node<T>;
	s->m_value = value;
	s->pNextNode = m_top;
	m_top = s;
}

template <class T>
T CLinkStack<T>::Pop()
{
	if (m_top != NULL)
	{
		int value = m_top->m_value;
		Node<T>* s = m_top;
		m_top = m_top->pNextNode;
		delete s;
		return value;
	}
	throw "链栈无元素";
}

template <class T>
T CLinkStack<T>::GetTop()
{
	if (m_top != NULL)
	{
		return m_top->m_value;
	}
	throw "链栈无元素";
}

template <class T>
bool CLinkStack<T>::Empty()
{
	return m_top == NULL ? true : false;
}
3)顺序栈和链栈的比较

它们的基本操作的算法都需要常数时间,所以唯一可以比较的就是空间性能.顺序栈在初始化时比较指定大小的空间,且被限制,所以有空间浪费和元素限制问题.而链栈没有空间限制,只有当内存无可用时.但是链栈需要一个指针域, 耗费了额外的存储空间.所以在栈的元素个数变化较大时,链栈是适宜的,反之,应采用顺序栈.


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值