※数据结构※→☆线性表结构(stack)☆============栈 链式存储结构(stack list)(七)

        栈(stack)在计算机科学中是限定仅在表尾进行插入或删除操作的线性表。栈是一种数据结构,它按照后进先出的原则存储数据,先进入的数据被压入栈底,最后的数据在栈顶,需要读数据的时候从栈顶开始弹出数据。栈是只能在某一端插入和删除的特殊线性表。用桶堆积物品,先堆进来的压在底下,随后一件一件往堆。取走时,只能从上面一件一件取。堆和取都在顶部进行,底部一般是不动的。栈就是一种类似桶堆积物品的数据结构,进行删除和插入的一端称栈顶,另一堆称栈底。插入一般称为进栈,删除则称为退栈。 栈也称为后进先出表。

        

基本概念

        首先系统或者数据结构栈中数据内容的读取与(压入push和 弹出pop)是两回事!插入是增加数据弹出是删除数据 ,这些操作只能从栈顶即最低地址作为约束的接口界面入手操作 ,但读取栈中的数据 是随便的 没有接口约束之说。很多人都误解这个理念从而对栈产生困惑。[1]而系统栈在计算机体系结构中 又起到一个跨部件交互的媒介区域的作用 即 cpu 与内存的交流通道 ,cpu只从系统给我们自己编写的应用程序所规定的栈入口线性地读取执行指令, 用一个形象的词来形容它就是pipeline(管道线、流水线)。cpu内部交互具体参见 EU与BIU的概念介绍。
        

栈特性

        栈作为一种数据结构,是一种只能在一端进行插入和删除操作的特殊线性表。它按照后进先出的原则存储数据,先进入的数据被压入栈底,最后的数据在栈顶,需要读数据的时候从栈顶开始弹出数据(最后一个数据被第一个读出来)。栈具有记忆作用,对栈的插入与删除操作中,不需要改变栈底指针。

        栈是允许在同一端进行插入和删除操作的特殊线性表。允许进行插入和删除操作的一端称为栈顶(top),另一端为栈底(bottom);栈底固定,而栈顶浮动;栈中元素个数为零时称为空栈。插入一般称为进栈(PUSH),删除则称为退栈(POP)。栈也称为后进先出表。

        栈可以用来在函数调用的时候存储断点,做递归时要用到栈!

栈与计算机
        在计算机系统中,栈则是一个具有以上属性的动态内存区域。程序可以将数据压入栈中,也可以将数据从栈顶弹出。在i386机器中,栈顶由称为esp的寄存器进行定位。压栈的操作使得栈顶的地址减小,弹出的操作使得栈顶的地址增大。
        

        栈在程序的运行中有着举足轻重的作用。最重要的是栈保存了一个函数调用时所需要的维护信息,这常常称之为堆栈帧或者活动记录。堆栈帧一般包含如下几方面的信息:
                1.函数的返回地址和参数
                2. 临时变量:包括函数的非静态局部变量以及编译器自动生成的其他临时变量。


栈算法

        进栈算法

                ①若TOP≥n时,则给出溢出信息,作出错处理(进栈前首先检查栈是否已满,满则溢出;不满则作②);
                ②置TOP=TOP+1(栈指针加1,指向进栈地址);
                ③S(TOP)=X,结束(X为新进栈的元素);


        退栈算法
                ①若TOP≤0,则给出下溢信息,作出错处理(退栈前先检查是否已为空栈, 空则下溢;不空则作②);
                ②X=S(TOP),(退栈后的元素赋给X);
                ③TOP=TOP-1,结束(栈指针减1,指向栈顶)。
        


链式存储结构
        在计算机中用一组任意的存储单元存储线性表的数据元素(这组存储单元可以是连续的,也可以是不连续的).
        它不要求逻辑上相邻的元素在物理位置上也相邻.因此它没有顺序存储结构所具有的弱点,但也同时失去了顺序表可随机存取的优点.


        链式存储结构特点:
                1、比顺序存储结构的存储密度小 (每个节点都由数据域和指针域组成,所以相同空间内假设全存满的话顺序比链式存储更多)。
                2、逻辑上相邻的节点物理上不必相邻。
                3、插入、删除灵活 (不必移动节点,只要改变节点中的指针)。
                4、查找结点时链式存储要比顺序存储慢。
                5、每个结点是由数据域和指针域组成。


~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
以后的笔记潇汀会尽量详细讲解一些相关知识的,希望大家继续关注、支持、顶起我的博客。
你们的关注就是我的动力,本节笔记到这里就结束了。


潇汀一有时间就会把自己的学习心得,觉得比较好的知识点写出来和大家一起分享。
编程开发的路很长很长,非常希望能和大家一起交流,共同学习,共同进步。
如果文章中有什么疏漏的地方,也请大家留言指正。也希望大家可以多留言来和我探讨编程相关的问题。
最后,谢谢你们一直的支持~~~
------------------------------------------
Country: China
Tel: +86-152******41
QQ: 451292510
E-mail: xiaoting_chen2010@163.com
------------------------------------------


       C++完整个代码示例(代码在VS2005下测试可运行)

       


AL_Node.h

/**
  @(#)$Id: AL_Node.h 44 2013-09-13 08:50:04Z xiaoting $
  @brief	store data, and be used to AL_ListSingle, AL_ListDouble, AL_ListCircular and so on

  Chain storage structure//
  The computer using a set of arbitrary linear table storage unit stores data elements (which may be a continuous plurality of memory cells, it can be discontinuous).
  It does not require the logic elements of adjacent physical location is adjacent to and therefore it is not sequential storage structure has a weakness, but also lost the sequence table can be accessed randomly advantages.

  Chain store structural features:
	1, compared with sequential storage density storage structure (each node consists of data fields and pointers domains, so the same space is full, then assume full order of more than chain stores).
	2, the logic is not required on the adjacent node is physically adjacent.
	3, insert, delete and flexible (not the mobile node, change the node as long as the pointer).
	4, find the node when stored sequentially slower than the chain stores.
	5, each node is a pointer to the data fields and domains.

  @Author $Author: xiaoting $
  @Date $Date: 2013-09-13 16:50:04 +0800 (周五, 13 九月 2013) $
  @Revision $Revision: 44 $
  @URL $URL: https://svn.code.sf.net/p/xiaoting/game/trunk/MyProject/AL_DataStructure/groupinc/AL_Node.h $
  @Header $Header: https://svn.code.sf.net/p/xiaoting/game/trunk/MyProject/AL_DataStructure/groupinc/AL_Node.h 44 2013-09-13 08:50:04Z xiaoting $
 */

#ifndef CXX_AL_NODE_H
#define CXX_AL_NODE_H

///
//			AL_Node
///

template<typename T> class AL_ListSingle;
template<typename T> class AL_ListDouble;
template<typename T> class AL_ListCircularSingle;
template<typename T> class AL_ListCircularDouble;
template<typename T> class AL_StackList;
template<typename T> class AL_QueueList;
template<typename T> class AL_QueuePriorityList;

template<typename T> 
class AL_Node
{
public:
	/**
	* Destruction
	*
	* @param
	* @return
	* @note
	* @attention 
	*/
	~AL_Node();

protected:
private:
	friend class AL_ListSingle<T>;
	friend class AL_ListDouble<T>;
	friend class AL_ListCircularSingle<T>;
	friend class AL_ListCircularDouble<T>;
	friend class AL_StackList<T>;
	friend class AL_QueueList<T>;
	friend class AL_QueuePriorityList<T>;
	
	/**
	* Construction
	*
	* @param
	* @return
	* @note		private the Construction, avoid the others use it
	* @attention
	*/
	AL_Node();
	
	/**
	* Construction
	*
	* @param const T& tTemplate <IN>
	* @return
	* @note
	* @attention private the Construction, avoid the others use it
	*/
	AL_Node(const T& tTemplate);

public:
protected:
private:
	T m_data;				//the friend class can use it directly
	AL_Node *m_pPre;			//previous data			AL_ListDouble will use it
	AL_Node *m_pNext;			//next data
};

///
//			AL_Node
///

/**
* Construction
*
* @param
* @return
* @note		private the Construction, avoid the others use it
* @attention
*/
template<typename T>
AL_Node<T>::AL_Node():
m_pPre(NULL),
m_pNext(NULL)
{
	//memset(&m_data, 0x00, sizeof(T));		//can not use memset, as to pointer or virtural pointer of class
}

/**
* Construction
*
* @param const T& tTemplate <IN>
* @return
* @note
* @attention private the Construction, avoid the others use it
*/
template<typename T>
AL_Node<T>::AL_Node(const T& tTemplate):
m_data(tTemplate),
m_pPre(NULL),
m_pNext(NULL)
{

}


/**
* Destruction
*
* @param
* @return
* @note
* @attention 
*/
template<typename T>
AL_Node<T>::~AL_Node()
{
	//it doesn't matter to clear the pointer or not.
	m_pPre = NULL;
	m_pNext = NULL;
}

#endif // CXX_AL_NODE_H
/* EOF */

AL_StackList.h

/**
  @(#)$Id: AL_StackList.h 44 2013-09-13 08:50:04Z xiaoting $
  @brief     Stack (stack) in computer science is limited only in the end of the table to insert or delete operations linear form. 
  A stack is a data structure that in accordance with the principle of LIFO data storage, data is first pushed into the end of the 
  last data in the stack, you need to read the data when the data from the topmost pop. The stack is only one end of the inserted 
  and deleted special linear form. Buckets stacked items, first came under pressure in the heap, followed by a one to the heap. 
  Removed, only a one taken from above. Take the top of the heap and are carried at the bottom of the general is not moving. Stack 
  is a similar data structure barrels stacked items, delete and insert one end of said stack, said another pile bottom of the stack. 
  Insert commonly known as the push to delete is called the stack back. Also known as LIFO stack table.

  @Author $Author: xiaoting $
  @Date $Date: 2013-09-13 16:50:04 +0800 (周五, 13 九月 2013) $
  @Revision $Revision: 44 $
  @URL $URL: https://svn.code.sf.net/p/xiaoting/game/trunk/MyProject/AL_DataStructure/groupinc/AL_StackList.h $
  @Header $Header: https://svn.code.sf.net/p/xiaoting/game/trunk/MyProject/AL_DataStructure/groupinc/AL_StackList.h 44 2013-09-13 08:50:04Z xiaoting $
 */

#ifndef CXX_AL_STACKLIST_H
#define CXX_AL_STACKLIST_H

///
//			AL_StackList
///

template<typename T>  
class AL_StackList
{
public:
	/**
	* Construction
	*
	* @param
	* @return
	* @note
	* @attention
	*/
	AL_StackList();

	/**
	* Destruction
	*
	* @param
	* @return
	* @note
	* @attention
	*/
	~AL_StackList();

	/**
	* IsEmpty
	*
	* @param	VOID
	* @return	BOOL
	* @note		Returns true stack is empty
	* @attention
	*/
	BOOL IsEmpty() const;

	/**
	* Pop
	*
	* @param	T& tTypeOut <OUT>
	* @return	BOOL
	* @note		Remove the top element and return data top element
	* @attention	if empty does not return a value... (please judge the stack is empty before use it)
	*/
	BOOL Pop(T& tTypeOut);

	/**
	* Push
	*
	* @param	const T& tTemplate
	* @return	BOOL
	* @note		Add elements in the stack
	* @attention
	*/
	BOOL Push(const T& tTemplate);

	/**
	* Size
	*
	* @param	VOID
	* @return	DWORD
	* @note		Returns the number of elements in the stack
	* @attention
	*/
	DWORD Size() const;
	
	/**
	* Top
	*
	* @param	T& tTypeOut <OUT>
	* @return	BOOL
	* @note		Back to the top element...
	* @attention	if empty does not return a value... (please judge the stack is empty before use it)
	*/
	BOOL Top(T& tTypeOut) const;

	/**
	* Clear
	*
	* @param	VOID
	* @return	VOID
	* @note		clear all data
	* @attention
	*/
	VOID Clear();
	
protected:
private:

public:
protected:
private: 
	AL_Node<T>*		m_pHeader;
	DWORD			m_dwSize;
};


/**
* Construction
*
* @param
* @return
* @note
* @attention
*/
template<typename T> 
AL_StackList<T>::AL_StackList():
m_pHeader(NULL),
m_dwSize(0x00)
{
	m_pHeader = new AL_Node<T>;
}

/**
* Destruction
*
* @param
* @return
* @note
* @attention
*/
template<typename T> 
AL_StackList<T>::~AL_StackList()
{
	if (NULL != m_pHeader) {
		delete m_pHeader;
		m_pHeader = NULL;
	}
}

/**
* IsEmpty
*
* @param	VOID
* @return	BOOL
* @note		Returns true stack is empty
* @attention
*/
template<typename T> BOOL 
AL_StackList<T>::IsEmpty() const
{
	return (NULL == m_pHeader->m_pNext) ? TRUE:FALSE;
}

/**
* Pop
*
* @param	T& tTypeOut <OUT>
* @return	BOOL
* @note		Remove the top element and return data top element
* @attention	if empty does not return a value... (please judge the stack is empty before use it)
*/
template<typename T> BOOL 
AL_StackList<T>::Pop(T& tTypeOut)
{
	if (TRUE == IsEmpty()) {
		return FALSE;
	}
	
	AL_Node<T>*	pPop = m_pHeader->m_pNext;
	tTypeOut = pPop->m_data;

	//delete the top
	m_pHeader->m_pNext = pPop->m_pNext;
	delete pPop;
	pPop = NULL;

	m_dwSize--;
	return TRUE;
}

/**
* Push
*
* @param	const T& tTemplate
* @return	BOOL
* @note		Add elements in the stack
* @attention
*/
template<typename T> BOOL
AL_StackList<T>::Push(const T& tTemplate)
{
	AL_Node<T>*	pPush = new AL_Node<T>;
	if (NULL == pPush) {
		//new error
		return FALSE;
	}

	pPush->m_data = tTemplate;
	pPush->m_pNext = m_pHeader->m_pNext;
	m_pHeader->m_pNext = pPush;

	m_dwSize++;
	return TRUE;
}

/**
* Size
*
* @param	VOID
* @return	DWORD
* @note		Returns the number of elements in the stack
* @attention
*/
template<typename T> DWORD 
AL_StackList<T>::Size() const
{
	return m_dwSize;
}

/**
* Top
*
* @param	T& tTypeOut <OUT>
* @return	BOOL
* @note		Back to the top element...
* @attention	if empty does not return a value... (please judge the stack is empty before use it)
*/
template<typename T> BOOL 
AL_StackList<T>::Top(T& tTypeOut) const
{
	if (TRUE == IsEmpty()) {
		//Empty
		return FALSE;
	}
	
	AL_Node<T>*	pTop = m_pHeader->m_pNext;
	tTypeOut = pTop->m_data;
	return TRUE;
}

/**
* Clear
*
* @param	VOID
* @return	VOID
* @note		clear all data
* @attention
*/
template<typename T> VOID 
AL_StackList<T>::Clear()
{
	AL_Node<T>* pDelete = NULL;
	while(NULL != m_pHeader->m_pNext){
		//get the node
		pDelete = m_pHeader->m_pNext;
		m_pHeader->m_pNext = pDelete->m_pNext;
		delete pDelete;
		pDelete = NULL;
	}
	m_dwSize = 0x00;
}
#endif // CXX_AL_STACKLIST_H
/* EOF */


测试代码

#ifdef TEST_AL_STACKLIST
	AL_StackList<DWORD> cStackList;
	BOOL bEmpty = cStackList.IsEmpty();
	std::cout<<bEmpty<<std::endl;
	DWORD dwPop = 0x00;
	cStackList.Pop(dwPop);
	std::cout<<dwPop<<std::endl;
	DWORD dwSize = cStackList.Size();
	std::cout<<dwSize<<std::endl;
	DWORD dwTop = 0x00;
	cStackList.Top(dwTop);
	std::cout<<dwTop<<std::endl;

	for (WORD wCnt=1; wCnt<16; wCnt++) {
		//push 15 14 13 12.....
		cStackList.Push(16 - wCnt);
		cStackList.Top(dwTop);
		std::cout<<dwTop<<std::endl;
	}

	bEmpty = cStackList.IsEmpty();
	std::cout<<bEmpty<<std::endl;
	dwSize = cStackList.Size();
	std::cout<<dwSize<<std::endl;

	while (0x00 != cStackList.Size()) {
		cStackList.Pop(dwPop);
		std::cout<<dwPop<<std::endl;
	}

	cStackList.Push(999);
	cStackList.Push(888);
	cStackList.Clear();
	bEmpty = cStackList.IsEmpty();
	std::cout<<bEmpty<<std::endl;
#endif





  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值