链表实现的栈可以克服在程序运行时也无法估计栈容量大小的情况;
栈中的元素是存储在称为节点的类中,每个节点都包含一个数据域和一个指针域;数据域存储栈的值,指针域指示栈中下一个值得位置;而栈类的数据成员是需要一个指向栈顶的指针即可;
类声明如下:
typedef int StackElement;
class stack
{
public :
stack ();
stack (const stack & original);
~stack ();
const stack & operator = (const stack & right);
bool empty () const;
void push (const StackElement item);
void pop ();
StackElement top () const;
void display (ostream & out) const;
private :
//** 节点类 **//
class Node
{
public :
StackElement date;
Node * next;
Node (StackElement value,Node * link=0) : date(value),next(link) {}
};
typedef Node * NodePointer;
NodePointer myTop;
};
由类声明可知,创建一个空栈只需令myTop为空指针来表示他没有指向任何节点即可;
相应的 empty 函数就只需要检查myTop是否为 0 来判断栈是否为空;
push 函数:(1)建立一个节点,(2)把节点的指针域指向myTop指示的位置并同时把数据域赋插入的值;(3)myTop指向新节点;
代码:myTop = new (nothrow) stack::Node (item,myTop);
提取栈顶元素和基于数组的栈一样;而删除栈的实现,也相差无几;只需令另一个指针指向栈顶指针,然后栈顶指针下移,最后删除另一个指针即可:stack::NodePointer Ptr = myTop; myTop = myTop-> next; delete Ptr;
遍历栈元素的代码:
<span style="white-space:pre"> </span>stack::NodePointer currptr = myTop,nextptr;
while (currptr)
{
nextptr = currptr -> next;
delete currptr;
currptr = nextptr;
}
具体实现代码:
#include <iostream>
using namespace std;
typedef int StackElement;
class stack
{
public :
stack ();
stack (const stack & original);
~stack ();
const stack & operator = (const stack & right);
bool empty () const;
void push (const StackElement item);
void pop ();
StackElement top () const;
void display (ostream & out) const;
private :
//** 节点类 **//
class Node
{
public :
StackElement date;
Node * next;
Node (StackElement value,Node * link=0) : date(value),next(link) {}
};
typedef Node * NodePointer;
NodePointer myTop;
};
// 构造函数
stack::stack () : myTop (0) {}
// 复制构造函数
stack::stack (const stack & original)
{
myTop = 0;
if (!original.empty ())
{
myTop = new (nothrow) stack::Node(original.top()); //复制栈顶元素
stack::NodePointer lastptr = myTop,origptr=original.myTop->next;
// 遍历栈元素
while (origptr)
{
lastptr->next = new (nothrow) stack::Node (origptr->date);
lastptr = lastptr->next;
origptr = origptr->next;
}
}
}
//赋值运算符的定义
const stack & stack::operator = (const stack & right)
{
if (this != &right)
{
this -> ~stack (); //销毁当前链表
if (right.empty ())
myTop = 0;
else
{
myTop = new (nothrow) stack::Node (right.top());
stack::NodePointer lastPtr=myTop,rhsPtr = right.myTop -> next;
while (rhsPtr)
{
lastPtr -> next = new (nothrow) stack::Node (rhsPtr->date);
lastPtr = lastPtr -> next;
rhsPtr = rhsPtr -> next;
}
}
}
return *this;
}
// 析构函数
stack::~stack ()
{
stack::NodePointer currptr = myTop,nextptr;
while (currptr)
{
nextptr = currptr -> next;
delete currptr;
currptr = nextptr;
}
}
bool stack::empty () const
{
return myTop == 0;
}
void stack::push (const StackElement item)
{
myTop = new (nothrow) stack::Node (item,myTop);
}
void stack::display (ostream & out) const
{
stack::NodePointer Ptr;
for (Ptr=myTop; Ptr!=0; Ptr = Ptr->next)
out << Ptr->date << endl;
}
StackElement stack::top () const
{
if (!empty ())
return (myTop->date);
else
{
StackElement * tmp = new (StackElement);
StackElement garbage = *tmp;
delete tmp;
return garbage;
}
}
void stack::pop ()
{
if (!empty ())
{
stack::NodePointer Ptr = myTop;
myTop = myTop-> next;
delete Ptr;
}
else
cerr << "stack is Empty\n";
}
int main ()
{
stack s;
cout << "stack created.Empty ?\n" << (s.empty ()?"YES":"NO") << endl;
cout << "How many element to add the stack ?\n";
int number;
cin >> number;
for (int i=1; i<=number; i++)
{
cout << i*10 << " add to the top\n";
s.push (i*10);
}
cout << "stack created.Empty ?\n" << (s.empty ()?"YES":"NO") << endl;
cout << "stack is : \n";
s.display (cout);
cout <<"created stack u,v;u=v=s: \n";stack u,v;
u = v = s;
cout << "u: \n";
u.display (cout);
cout << "Poping v:\n";
while (!v.empty ())
{
cout << "Popint " << v.top () << endl;
v.pop ();
}
cout << "stack created.Empty ?\n" << (v.empty ()?"YES":"NO") << endl;
return 0;
}