基本数据结构(3) —— 栈

1

栈(stack),在计算机科学中,是一种特殊的串行形式的数据结构,它的特殊之处在于只能允许在链结串行或阵列的一端(称为栈顶,top)进行加入(push)和输出(pop)的运算。栈可以用一维动态数组或链表的形式来完成。

 

由于堆栈数据结构只允许在一端进行操作,因而按照后进先出(LIFO, Last In First Out)的原理运作。堆栈数据结构使用两种基本操作:推入(push)和弹出(pop):

推入(push):将数据放入堆栈的顶端(阵列形式或串行形式),堆栈顶端top指标加一。

弹出(pop):将顶端数据资料输出(回传),堆栈顶端资料减一。

 

先来看栈的架构设计:

首先来看抽象栈实现方式:

class Stack : public virtual Container
{
public:
	virtual Object& Top () const = 0;
	virtual void Push (Object&) = 0;
	virtual Object& Pop () = 0;
};

再来看栈的动态数组实现方式:

class StackAsArray : public Stack
{
	Array<Object*> array;

	class Iter;
public:
	StackAsArray (unsigned int size);
	~StackAsArray ();
	// ...
	Object& Top() const;
	void Push(Object& obj);
	Object& Pop();

	void Purge ();
	void Accept (Visitor& visitor) const;
	Iterator& NewIterator() const;

	friend class Iter;
};

StackAsArray::StackAsArray( unsigned int size )
:array(size)
{
	count = 0;
}

void StackAsArray::Purge()
{
	if (IsOwner())
	{
		for (unsigned int i = 0; i < count; ++i)
		{
			delete array [i];
		}
	}
	count = 0;
}

StackAsArray::~StackAsArray()
{
	Purge ();
}

Object& StackAsArray::Top() const
{
	if (count == 0)
	{
		throw domain_error ("stack is empty");
	}
	return *array [count - 1U];
}

void StackAsArray::Push( Object& obj )
{
	if (count == array.Length ())
	{
		throw domain_error ("stack is full");
	}
	array [count++] = &obj;
}

Object& StackAsArray::Pop()
{
	if (count == 0)
	{
		throw domain_error ("stack is empty");
	}
	return *array [--count];
}

void StackAsArray::Accept( Visitor& visitor ) const
{
	for (unsigned int i = 0;
		i < count && !visitor.IsDone (); ++i)
	{
		visitor.Visit (*array [i]);
	}
}

Iterator& StackAsArray::NewIterator() const
{
	return *new StackAsArray::Iter(*this);
}


 

注意最后一个函数,返回StackAsArray内部类Iter,这是一个迭代器模式的典型应用:

class StackAsArray::Iter : public Iterator
{
	StackAsArray const& stack;
	unsigned int position;
public:
	Iter (StackAsArray const& _stack);
	// ...
	bool IsDone () const;
	Object& operator * () const;
	void operator ++ ();
	void Reset ();
};

StackAsArray::Iter::Iter( StackAsArray const& _stack )
:stack (_stack)
{
	Reset();
}

bool StackAsArray::Iter::IsDone() const
{
	return position >= stack.count;
}

Object& StackAsArray::Iter::operator*() const
{
	if (position < stack.count)
	{
		return *stack.array[position];
	}
	else
	{
		return NullObject::Instance ();
		//return NULL;
	}
}

void StackAsArray::Iter::operator++()
{
	if (position < stack.count)
	{
		++position;
	}
}

void StackAsArray::Iter::Reset()
{
	position = 0;
}


 

接下来看栈的链表实现方式:

class StackAsLinkedList : public Stack
{
	LinkedList<Object*> list;

	class Iter;
public:
	StackAsLinkedList ();
	~StackAsLinkedList ();
	void Purge();
	void Accept (Visitor& visitor) const;
	Iterator& NewIterator() const;

	// ...
	void Push (Object& object);
	Object& Pop ();
	Object& Top () const;

	friend class Iter;
};


class StackAsLinkedList::Iter : public Iterator
{
	StackAsLinkedList const& stack;
	ListElement<Object*> const* position;
public:
	Iter (StackAsLinkedList const& _stack);

	// ...
	bool IsDone () const;
	Object& operator * () const;
	void operator ++ ();
	void Reset ();
};

StackAsLinkedList::StackAsLinkedList()
:list()
{

}

void StackAsLinkedList::Purge()
{
	if (IsOwner ())
	{
		ListElement<Object*> const* ptr;

		for (ptr = list.Head (); ptr != 0; ptr = ptr->Next ())
		{
			delete ptr->Datum ();
		}
	}
	list.Purge ();
	count = 0;
}

StackAsLinkedList::~StackAsLinkedList()
{
	Purge();
}

void StackAsLinkedList::Push( Object& object )
{
	list.Prepend (&object);
	++count;
}

Object& StackAsLinkedList::Pop()
{
	if (count == 0)
	{
		throw domain_error ("stack is empty");
	}
	Object& result = *list.First ();
	list.Extract (&result);
	--count;
	return result;
}

Object& StackAsLinkedList::Top() const
{
	if (count == 0)
	{
		throw domain_error ("stack is empty");
	}
	return *list.First ();
}

void StackAsLinkedList::Accept( Visitor& visitor ) const
{
	ListElement<Object*> const* ptr;

	for (ptr = list.Head ();
		ptr != 0 && !visitor.IsDone (); ptr = ptr->Next ())
	{
		visitor.Visit (*ptr->Datum ());
	}
}

Iterator& StackAsLinkedList::NewIterator() const
{
	return *new StackAsLinkedList::Iter(*this);
}

StackAsLinkedList::Iter::Iter( StackAsLinkedList const& _stack )
:stack (_stack)
{
	Reset ();
}

bool StackAsLinkedList::Iter::IsDone() const
{
	return position == 0;
}

Object& StackAsLinkedList::Iter::operator*() const
{
	if (position != 0)
	{
		return *position->Datum ();
	}
	else
	{
		return NullObject::Instance ();
	}
}

void StackAsLinkedList::Iter::operator++()
{
	if (position != 0)
	{
		position = position->Next ();
	}
}

void StackAsLinkedList::Iter::Reset()
{
	position = stack.list.Head ();


 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值