- 《算法導論》10.1-2 如何在一個數組[1...n]中實現兩個棧,使得當兩個棧的元素個數之和不爲n時,二者都不會發生上溢。要求push和pop操做的運行時間爲O(1)。
#include <iostream>
template<typename Object>
class DoubleStack
{
public:
DoubleStack(){init();}
DoubleStack(const DoubleStack& rhs)
{
init();
top1 = rhs.top1;
top2 = rhs.top2;
int i, idx;
for(i = 0; i != top1 + 1; ++i)
{
idx = index1(i);
p[idx] = rhs.p[idx];
}
for(i = 0; i != top2 + 1; ++i)
{
idx = index2(i);
p[idx] = rhs.p[idx];
}
}
DoubleStack(DoubleStack&& rhs):p(rhs.p),top1(rhs.top1),top2(rhs.top2)
{
rhs.p = nullptr;
rhs.top1 = -1;
rhs.top2 = -1;
}
DoubleStack& operator =(const DoubleStack& rhs)
{
DoubleStack copy(rhs);
std::swap(copy.p, this->p);
std::swap(copy.top1, this->top1);
std::swap(copy.top2, this->top2);
return *this;
}
DoubleStack& operator =(DoubleStack&& rhs)
{
std::swap(rhs.p, this->p);
std::swap(rhs.top1, this->top1);
std::swap(rhs.top2, this->top2);
return *this;
}
~DoubleStack()
{
if(p)
delete[] p;
}
void push1(const Object& object)
{
if(full())
std::cout << "overflow" << std::endl;
else
p[index1(++top1)] = object;
}
void push1(Object&& object)
{
if(full())
std::cout << "overflow" << std::endl;
else
p[index1(++top1)] = std::move(object);
}
void push2(const Object& object)
{
if(full())
std::cout << "overflow" << std::endl;
else
p[index2(++top2)] = object;
}
void push2(Object&& object)
{
if(full())
std::cout << "overflow" << std::endl;
else
p[index2(++top2)] = std::move(object);
}
Object top_1() const
{
return p[index1(top1)];
}
Object top_2() const
{
return p[index2(top2)];
}
void pop1()
{
if(empty1())
std::cout << "underflow" << std::endl;
else
--top1;
}
void pop2()
{
if(empty2())
std::cout << "underflow" << std::endl;
else
--top2;
}
bool empty1() const{return top1 == -1;}
bool empty2() const{return top2 == -1;}
bool full() const{return top1 + top2 + 2 == MAX_SIZE;}
private:
static constexpr int MAX_SIZE = 4;
Object* p;
int top1;
int top2;
void init()
{
p = new Object[MAX_SIZE];
top1 = top2 = -1;
}
inline int index1(int top) const
{
return top;
}
inline int index2(int top) const
{
return MAX_SIZE -1 -top;
}
};
void testDoubleStack()
{
using namespace std;
struct Student
{
char name[10];
int age;
};
DoubleStack<Student> ds;
ds.push1(Student{"Tom", 12});
ds.push1(Student{"Micheal", 13});
ds.push1(Student{"Anna", 14});
ds.push1(Student{"Lily", 10});
ds.push1(Student{"James", 19});
while(!ds.empty1())
{
auto stu = ds.top_1();
ds.pop1();
ds.push2(stu);
}
decltype(ds) ds_copy(ds);
decltype(ds) ds_move(std::move(ds));
while(!ds_copy.empty2())
{
Student stu = ds_copy.top_2();
cout << "name: " << stu.name << " age: " << stu.age << endl;
ds_copy.pop2();
}
while(!ds_move.empty2())
{
Student stu = ds_move.top_2();
cout << "name: " << stu.name << " age: " << stu.age << endl;
ds_move.pop2();
}
/*output:
overflow
name: Tom age: 12
name: Micheal age: 13
name: Anna age: 14
name: Lily age: 10
name: Tom age: 12
name: Micheal age: 13
name: Anna age: 14
name: Lily age: 10
*/
}