一个数组实现两个栈
2018-03-07 11:18
148 查看
看到题目,首先要考虑什么是数组,什么是栈,两者的特性都是怎样的,其次再考虑如何实现题目要求。
通常会想到:
方法一:栈1从数组的开头开始,栈2从数组的末尾开始,这样比较节省空间,当栈1和栈2的栈顶相遇时,我们就进行扩容。
方法二:既然方法一可以从两边开始,那么我们也可以从中间开始向两边延伸,但这样有可能就会造成空间浪费,比如某一个栈分配了大量的空间,可是实际其只有一两个数据。
方法三:在讨论中,有的同学建议数组下标的偶数位填入栈1的元素,数组下标的奇数位填入栈2的元素。
这里我主要分享一下方法一:
首先我们考虑到需要两个栈s1和s2,需要栈顶_top1和栈顶_top2,还需要数组容量_capacity,当然还需要数组_a。我们采用模板函数,在类里实现,需要写构造函数,析构函数,栈1入栈,栈2入栈,栈1出栈,栈2出栈,定义栈1和栈2的大小,是否为空,栈顶在何处,其次就要进行很重要的一步:检查容量。检查容量我们要考虑有两种特殊情况,一种是数组为空,另一种是数组为满,为空比较简单,为满我们就需要将原有的容量进行记录,扩充新的容量,设置一个指针tmp,指向扩充后的新数组,然后先将栈1的元素一次从前到后插入数组中,然后将栈2的元素从后向前依次插入数组中,然后再将_top2指向新的位置即可。
代码如下:
#include <iostream>
using namespace std;
template<class T>
class TwoStack //类TwoStack
{
public:
TwoStack() //构造函数
:_a(NULL)
, _top1(0)
, _top2(0)
, _capacity(0)
{
_CheckCapacity();
}
~TwoStack() //析构函数
{
if (_a)
delete[] _a;
}
void push1(const T& d) //栈1插入元素d
{
_CheckCapacity(); //检查是否有空间
_a[_top1++] = d; //有空间就将元素d插入到数组中,_Top1++
}
void push2(const T& d) //栈2同上插入元素
{
_CheckCapacity();
_a[_top2--] = d;
}
void pop1() //栈1元素出栈
{
if (_top1>0)
{
_top1--;
}
}
void pop2() //栈2元素出栈
{
if (_top2<_capacity-1)
{
_top2++;
}
}
size_t Size1()
{
return _top1;
}
size_t Size2()
{
return _capacity-1-_top2;
}
bool Empty1()
{
return _top1 == 0;
}
bool Empty2()
{
return _top2 == _capacity-1;
}
T& Top1()
{
if (_top1 > 0)
{
return _a[_top1 - 1];
}
}
T& Top2()
{
if (_top2 <_capacity-1)
{
return _a[_top2 + 1];
}
}
private:
void _CheckCapacity()
{
if (_a == NULL)
{
_capacity += 3;
_a = new T[_capacity];
_top2 = _capacity - 1;
return;
}
if (_top1 == _top2)
{
size_t OldCapacity = _capacity;
_capacity = _capacity * 2;
T* tmp = new T[_capacity];//指针tmp指向扩容后的数组
for (size_t i = 0; i < _top1; i++)
{
tmp[i] = _a[i];//把原数组_a里面的栈1的元素从前向后依次赋值给新数组
} //当前数组与之前数组的第一个位置都是i
for (size_t j = OldCapacity - 1, i = _capacity - 1; j>_top2; j--, i--)
{
tmp[i] = _a[j];//把原数组_a里面的栈2的元素从后向前依次赋值给新数组
} //此刻j为之前数组的最后一个位置,i为新数组的最后一个位置
delete[] _a;
_a = tmp;
_top2 += _capacity / 2;
}
}
private:
T* _a;
size_t _top1;
size_t _top2;
size_t _capacity;
};
int main()
{
TwoStack<int> s;
s.push1(1);
s.push1(3);
s.push1(5);
s.push1(7);
s.push1(9);
s.push1(11);
s.push2(2);
s.push2(4);
s.push2(8);
s.push2(10);
cout << "s1:"<<s.Size1() << endl;
cout << "s2:"<<s.Size2() << endl;
while (!s.Empty1())
{
cout << s.Top1() << endl;
s.pop1();
}
while (!s.Empty2())
{
cout << s.Top2() << endl;
s.pop2();
}
system("pause");
}
通常会想到:
方法一:栈1从数组的开头开始,栈2从数组的末尾开始,这样比较节省空间,当栈1和栈2的栈顶相遇时,我们就进行扩容。
方法二:既然方法一可以从两边开始,那么我们也可以从中间开始向两边延伸,但这样有可能就会造成空间浪费,比如某一个栈分配了大量的空间,可是实际其只有一两个数据。
方法三:在讨论中,有的同学建议数组下标的偶数位填入栈1的元素,数组下标的奇数位填入栈2的元素。
这里我主要分享一下方法一:
首先我们考虑到需要两个栈s1和s2,需要栈顶_top1和栈顶_top2,还需要数组容量_capacity,当然还需要数组_a。我们采用模板函数,在类里实现,需要写构造函数,析构函数,栈1入栈,栈2入栈,栈1出栈,栈2出栈,定义栈1和栈2的大小,是否为空,栈顶在何处,其次就要进行很重要的一步:检查容量。检查容量我们要考虑有两种特殊情况,一种是数组为空,另一种是数组为满,为空比较简单,为满我们就需要将原有的容量进行记录,扩充新的容量,设置一个指针tmp,指向扩充后的新数组,然后先将栈1的元素一次从前到后插入数组中,然后将栈2的元素从后向前依次插入数组中,然后再将_top2指向新的位置即可。
代码如下:
#include <iostream>
using namespace std;
template<class T>
class TwoStack //类TwoStack
{
public:
TwoStack() //构造函数
:_a(NULL)
, _top1(0)
, _top2(0)
, _capacity(0)
{
_CheckCapacity();
}
~TwoStack() //析构函数
{
if (_a)
delete[] _a;
}
void push1(const T& d) //栈1插入元素d
{
_CheckCapacity(); //检查是否有空间
_a[_top1++] = d; //有空间就将元素d插入到数组中,_Top1++
}
void push2(const T& d) //栈2同上插入元素
{
_CheckCapacity();
_a[_top2--] = d;
}
void pop1() //栈1元素出栈
{
if (_top1>0)
{
_top1--;
}
}
void pop2() //栈2元素出栈
{
if (_top2<_capacity-1)
{
_top2++;
}
}
size_t Size1()
{
return _top1;
}
size_t Size2()
{
return _capacity-1-_top2;
}
bool Empty1()
{
return _top1 == 0;
}
bool Empty2()
{
return _top2 == _capacity-1;
}
T& Top1()
{
if (_top1 > 0)
{
return _a[_top1 - 1];
}
}
T& Top2()
{
if (_top2 <_capacity-1)
{
return _a[_top2 + 1];
}
}
private:
void _CheckCapacity()
{
if (_a == NULL)
{
_capacity += 3;
_a = new T[_capacity];
_top2 = _capacity - 1;
return;
}
if (_top1 == _top2)
{
size_t OldCapacity = _capacity;
_capacity = _capacity * 2;
T* tmp = new T[_capacity];//指针tmp指向扩容后的数组
for (size_t i = 0; i < _top1; i++)
{
tmp[i] = _a[i];//把原数组_a里面的栈1的元素从前向后依次赋值给新数组
} //当前数组与之前数组的第一个位置都是i
for (size_t j = OldCapacity - 1, i = _capacity - 1; j>_top2; j--, i--)
{
tmp[i] = _a[j];//把原数组_a里面的栈2的元素从后向前依次赋值给新数组
} //此刻j为之前数组的最后一个位置,i为新数组的最后一个位置
delete[] _a;
_a = tmp;
_top2 += _capacity / 2;
}
}
private:
T* _a;
size_t _top1;
size_t _top2;
size_t _capacity;
};
int main()
{
TwoStack<int> s;
s.push1(1);
s.push1(3);
s.push1(5);
s.push1(7);
s.push1(9);
s.push1(11);
s.push2(2);
s.push2(4);
s.push2(8);
s.push2(10);
cout << "s1:"<<s.Size1() << endl;
cout << "s2:"<<s.Size2() << endl;
while (!s.Empty1())
{
cout << s.Top1() << endl;
s.pop1();
}
while (!s.Empty2())
{
cout << s.Top2() << endl;
s.pop2();
}
system("pause");
}
相关文章推荐
- 将两个排好序的序列合并成一个(指针和数组分别实现)
- 算法导论学习10.1 两个栈共享一个数组 and 两个栈实现一个队列 and 两个队列实现一个栈
- 用一个数组实现两个堆栈,最大地使用数组的空间,只要有空间就能入栈成功
- 4-7 在一个数组中实现两个堆栈 (20分) PTA
- 在一个数组中实现两个堆栈
- 10.1-2 在一个数组A[1..n]中实现两个栈,使得两个栈元素个数之和不为n时,两者不会上溢
- 一个数组实现两个栈
- 一个数组实现两个栈
- 数据结构:请用一个数组实现两个堆栈,要求最大地利用数组空间,使 数组只要有空间入栈操作就可以成功
- 4-7 在一个数组中实现两个堆栈
- .一个数组中只有两个数字是出现一次,其他所有数字都出现了两次。 找出这两个数字,编程实现。
- 一个数组实现两个栈
- 一个数组实现两个栈
- 一个数组实现两个栈
- 一个数组中只有两个数字是出现一次,其他所有数字都出现了两次。找出这两个数字,编程实现。
- ~一个数组实现两个栈~
- git是一种分布式代码管理工具,git通过树的形式记录文件的更改历史,比如: base'<--base<--A<--A' ^ | --- B<--B' 小米工程师常常需要寻找两个分支最近的分割点,即base.假设git 树是多叉树,请实现一个算法,计算git树上任意两点的最近分割点。 (假设git树节点数为n,用邻接矩阵的形式表示git树:字符串数组matrix包含n个字符串,每个字符串由字符'0
- 4-7 在一个数组中实现两个堆栈 (20分)
- 栈 - 在一个长度为n的数组中实现两个栈(C++)
- Java实现把两个数组合并为一个的方法总结