一个数组实现共享栈是一个经典的算法,这些年也备受笔试/面试的青睐,其核心思想不难,但是对于临界点的把握是比较容易出错的,下面列举出两种常用方法。

1.奇偶占位法

如下图所示,对stack1进行偶数位压栈,对stack2进行奇数位压栈。top即栈顶,分别指向当前栈中最后一个元素的下一个将要压栈的位置。栈的数据结构较为简单,这里就不对其push、pop等操作过多描述,对应此图进行操作是很容易实现的。

此方法的不足在于,如果stack1插入了很多元素,而stack2插入元素极少,那么将会浪费很多资源,造成浪费,因此不推荐大家使用。
【数据结构】数组实现两个栈即共享栈

#pragma once
#include <iostream>
#include <assert.h>
using namespace std;

template<class T>
class arr_2_stack
{
public:
	arr_2_stack()
		:_arr(NULL)
		,_top1(0)
		,_top2(1)
		,_size(0)
		,_capacity(0)
	{}
	~arr_2_stack()
	{
		delete[] _arr;
	}
	void push(const T& data,int flag);//入栈
	void pop(int flag );//出栈
	size_t size(int flag);//栈的大小
	T& top(int flag = 0);//栈顶元素
	bool empty(int flag);//判断栈空
	const size_t length(int flag)const;//栈的下标
	void PrintStack(int flag);//打印
protected:
	//扩容
	void CheckCapacity();
private:
	T* _arr;
	size_t _top1;//栈1的栈顶
	size_t _top2;//栈2的栈顶
	size_t _size;//有效元素的个数
	size_t _capacity;//容量
};

template<class T>
//扩容
void arr_2_stack<T>::CheckCapacity()
{
	if (_size >= _capacity)
	{
		size_t NewCapacity = _capacity * 2 + 3;
		T* tmp = new T[NewCapacity];
		for (size_t idx = 0; idx < _size; ++idx)
		{
			tmp[idx] = _arr[idx];
		}
		delete[] _arr;
		_arr = tmp;
		_capacity = NewCapacity;
	}
}
template<class T>
T& arr_2_stack<T>::top(int flag)
{
	//stack1
	if (flag == 0)
	{
		assert(_top1 > 0);
		return _arr[_top1 - 2];
	}
	//stack2
	else
	{
		assert(_top2 > 1);
		return _arr[_top2 - 2];
	}
}
template<class T>
void arr_2_stack<T>::push(const T& data, int flag)
{
	CheckCapacity();
	//stack1
	if (flag == 0)
	{
		_arr[_top1] = data;
		_top1 += 2;
		if (_top1 > _top2)
		{
			_size += 2;
		}
	}
	//stack2
	else
	{
		_arr[_top2] = data;
		_top2 += 2;
		if (_top2 > _top1)
		{
			_size += 2;
		}
	}
}
template<class T>
size_t arr_2_stack<T>::size(int flag)
{
	if (flag == 0)
		return _top1 >> 1;
	else
		return (_top2 - 1) >> 1;
}
template<class T>
const size_t arr_2_stack<T>::length(int flag)const
{
	if (flag == 0)
	{
		return _top1 - 2;
	}
	else
		return _top2 - 2;
}
template<class T>
void arr_2_stack<T>::PrintStack(int flag)
{
	if (flag == 0)
	{
		if (_top1 <= 0)
		{
			cout << "Stack1 empty..." << endl;
			return;
		}
		for (size_t idx = 0; idx <= length(flag); idx += 2)
			cout << _arr[idx] << " ";
		cout << endl;
	}
	else
	{
		if (_top2 <= 1)
		{
			cout << "Stack2 empty..." << endl;
			return;
		}
		for (size_t idx = 1; idx <= length(flag); idx += 2)
			cout << _arr[idx] << " ";
		cout << endl;
	}
}
template<class T>
bool arr_2_stack<T>::empty(int flag)
{
	if (flag == 0)
		return _top1 == 0;
	else
		return _top2 == 1;
}
template<class T>
void arr_2_stack<T>::pop(int flag)
{
	if (flag == 0)
	{
		if (_top1 <= 0)
		{
			cout << "Stack1 empty" << endl;
			return;
		}
		_top1 -= 2;
		if (_top1 > _top2)
			_size -= 2;
	}
	else
	{
		
		if (_top2 <= 0)
		{
			cout << "Stack2 empty" << endl;
			return;
		}
		_top2 -= 2;
		if (_top2 > _top1)
			_size -= 2;
	}
}

2.首尾相遇法

没有一张图解决不了的问题,如果有,那就两张。首尾相遇的算法思想也很简单,但是在扩容的时候要对stack2做特殊处理,将stack2的数据后移的同时,将stack2的栈顶_top2也后移。
【数据结构】数组实现两个栈即共享栈

#pragma once
#include <iostream>
#include <assert.h>
using namespace std;

template<class T>
class arr_2_stack
{
public:
	arr_2_stack()
		:_arr(NULL)
		,_top1(0)
		,_top2(0)
		,_capacity(0)
	{}
	~arr_2_stack()
	{
		delete[] _arr;
	}
	void push(const T& data,int flag);//入栈
	void pop(int flag );//出栈
	const size_t size(int flag)const;//栈的大小
	T& top(int flag = 0);//栈顶元素
	bool empty(int flag);//判断栈空
	const size_t length(int flag)const;//栈的下标
	void PrintStack(int flag);//打印
protected:
	//扩容
	void CheckCapacity();
private:
	T* _arr;
	int _top1;//栈1的栈顶
	int _top2;//栈2的栈顶
	int _capacity;//容量
};

template<class T>
void arr_2_stack<T>::CheckCapacity()
{
	if (_top1 == _top2)
	{
		int NewCapacity = 2 * _capacity + 2;
		T* tmp = new T[NewCapacity];
		for (size_t idx = 0; idx < _top1; ++idx)
			tmp[idx] = _arr[idx];
		int k = _capacity - 1;
		for (int idx = NewCapacity - 1; k > _top2; --idx, --k)
		{
			tmp[idx] = _arr[k];
		}
		delete[] _arr;
		_arr = tmp;
		size_t count = 0;//stack2的元素个数
		if (_capacity)
		{
			count = _capacity - 1 - _top2;
		}
		_capacity = NewCapacity;
		_top2 = _capacity - 1 - count;//修改stack2的栈顶
	}
}

template<class T>
void arr_2_stack<T>::push(const T& data, int flag)
{
	CheckCapacity();
	//stack1
	if (flag == 0)
		_arr[_top1++] = data;
	else
		_arr[_top2--] = data;
}

template<class T>
void arr_2_stack<T>::pop(int flag)
{
	if (flag == 0)
	{
		if (_top1 <= 0)
		{
			cout << "Stack1 empty..." << endl;
			return;
		}
		_top1--;
	}
	else
	{
		if (_top2 == _capacity - 1)
		{
			cout << "Stack2 empty..." << endl;
			return;
		}	
		_top2--;
	}
}

template<class T>
const size_t arr_2_stack<T>::size(int flag)const
{
	//stack1
	if (flag == 0)
		return _top1;
	else
		return _capacity - 1 - _top2;
}

template<class T>
T& arr_2_stack<T>::top(int flag)
{
	if (flag == 0)
		return _arr[_top1 - 1];
	else
		return _arr[_top2 + 1];
}

template<class T>
const size_t arr_2_stack<T>::length(int flag)const
{
	if (flag == 0)
	{
		return _top1 - 1;
	}
	else
		return _top2 + 1;
}

template<class T>
bool arr_2_stack<T>::empty(int flag)
{
	if (flag == 0)
		return _top1 == 0;
	else
		return _top2 == (_capacity - 1);
}

template<class T>
void arr_2_stack<T>::PrintStack(int flag)
{
	if (flag == 0)
	{
		if (_top1 <= 0)
		{
			cout << "Stack1 empty..." << endl;
			return;
		}
		for (size_t idx = 0; idx <= length(flag); ++idx)
			cout << _arr[idx] << " ";
		cout << endl;
	}
	else
	{
		if (_top2 == _capacity - 1)
		{
			cout << "Stack2 empty..." << endl;
			return;
		}
		for (size_t idx = _capacity - 1; idx > length(flag) ; --idx)
			cout << _arr[idx] << " ";
		cout << endl;
	}
}

//两种方法的测试用例

#include "Array2stack.h"
void Test1()
{
	/*arr_2_stack<int> _s;
	_s.push(1, 0);
	_s.push(2, 0);
	_s.push(3, 0);
	_s.push(10, 1);
	_s.push(20, 1);
	_s.push(30, 1);
	_s.push(40, 1);
	cout << _s.size(0) << endl;
	cout << _s.size(1) << endl;
	cout << _s.top(0) << endl;
	cout << _s.top(1) << endl;
	cout << _s.length(0) << endl;
	cout << _s.length(1) << endl;
	_s.PrintStack(0);
	_s.PrintStack(1);
	cout << _s.empty(0) << endl;
	cout << _s.empty(1) << endl;
	_s.PrintStack(0);
	_s.PrintStack(1);*/
}
void Test2()
{
	arr_2_stack<int> _s;
	_s.push(1, 0);
	_s.push(2, 0);
	_s.push(3, 0);
	_s.push(10, 1);
	_s.push(20, 1);
	_s.push(30, 1);
	_s.push(40, 1);
	_s.push(20, 1);
	_s.push(30, 1);
	_s.push(40, 1);
	_s.PrintStack(0);
	_s.PrintStack(1);
	/*_s.pop(0);
	_s.pop(0);
	_s.pop(1);
	_s.PrintStack(0);
	_s.PrintStack(1);*/
	cout << _s.size(0) << endl;
	cout << _s.size(1) << endl;
	cout << _s.top(0) << endl;
	cout << _s.top(1) << endl;
	cout << _s.empty(0) << endl;
	cout << _s.empty(1) << endl;
}
int main()
{
	//Test1();
	Test2();
	system("pause");
	return 0;
}

相关文章:

  • 2021-07-31
  • 2022-12-23
  • 2021-04-10
  • 2021-10-24
  • 2021-12-30
  • 2021-05-26
  • 2021-09-21
  • 2022-01-14
猜你喜欢
  • 2022-12-23
  • 2021-11-16
  • 2022-12-23
  • 2021-07-12
  • 2021-12-30
  • 2022-01-29
  • 2021-05-28
相关资源
相似解决方案