顺序栈与链栈的原理及代码实现

栈是一种仅能在表尾插入或删除的的数据结构。对于栈来说,表尾称为栈顶,表头为栈底,不含元素的表为空栈。

因为栈只能在栈顶这一端进行插入或删除,所以栈为先进后出(FILO)结构。

栈的一般实现为顺序栈或者链栈。

栈的基本操作

栈的初始化、判空、判满、取栈顶元素、在栈顶进行插入和删除。

在栈顶插入元素称为入栈,在栈顶删除元素称为出栈。

顺序栈的定义

#define Stack_Size 500//定义顺序栈大小
struct stack
{
    int top;//栈顶指针
    datatype elem[Stack_Size];//顺序栈数组
}SeqStack;

top :用来表示栈顶元素的位置;

top==-1表示空栈;

top==NULL表示栈不存在;

top>stacksize元素溢出。

链栈的定义

typedef int elemtype;  /设置数据类型/
typedef struct LinkedStackNode 
{	
	elemtype data;
	struct LinkedStackNode * next;
} LinkedStackNode, * LinkedStack;                                  
  LinkedStack top; /设置头指针/

链栈没有栈满问题,大小可以随时扩充;

插入和删除在栈顶处实行;

链式栈的栈顶在链头;

与单链表存储结构一致,与顺序表逻辑结构一致 。

栈的常见算法实现

push入栈,指针top向上移动

pop出栈,指针top向下移动

栈的初始化

//顺序栈
void InitStack(SeqStack *S)
 {	/ *构造一个空栈S*/
 S->top = -1;
 } 
//链栈
LinkedStack Init_LinkedStack()                                       
{	
	LinkedStack top=(LinkedStackNode * )malloc (sizeof( LinkedStackNode));
	if(top!=NULL)//申请空间成功
	top->next=NULL;//设置栈顶指针为空
	return top;
}

栈的判空

/ *顺序栈判栈空*/
 int IsEmpty(SeqStack *S)
 {     / *判断栈S为空栈时返回值为真,反之为假*/
 return(S->top==-1?1:0);
 } 
//链栈
int LinkedStack_Empty(LinkedStack top)                            
{	
	if(top->next==NULL)//检查栈顶指针的值 
	{
		return 1;//栈S为空,函数返回1
	}	
	else
	{
		return 0;
	}
}

判断栈满

/ *顺序栈判栈满*/
 int IsFull(SeqStack *S)	
 {   / *判断栈S为满栈时返回值为真,反之为假*/
 return(S->top==Stack_Size-1?1:0);
 } 

取栈顶元素

//顺序栈
int GetTop(SeqStack *S)
{  	
	if(S->top == -1)      /*栈为空*/
		return 0;
	else
	{
  		return S->elem[S->top];
	}	
}
//链栈
int GetTop_LinkedStack(LinkedStack top)                
{ 
	if(top->next)
      {
            return top->next->data;

      }
      return 0;
}

入栈

/ *顺序栈入栈*/
 int Push(SeqStack *S,StackElementType *x)
{
    */  将栈S的栈顶元素弹出,放到x所指的存储空间中 */
     if(S->top == Stack_Size-1)    / *栈满不能入栈*/
     return 0;
     else
    { 
        S->top++;   /* 修改栈顶指针 */
        S->elem[S->top] = x;
        return 1;
     }
 } 
int Push_LinkedStack(LinkedStack top,elemtype x)                     
	//插入数据元素x为新的栈顶元素
{	
	LinkedStackNode * node;
	node=(LinkedStackNode * )malloc(sizeof(LinkedStackNode));
	if(node==NULL)
	{
		return 0;//申请结点空间失败,插入失败,函数返回0
	}
	else
	{
		node->data=x;//设置新结点的数据域
		node->next=top->next;//设置新结点的指针城
		top->next=node;//设置头结点指针城指向新的栈顶元素
		return 1;//插入成功,函数返回1
	}
}

出栈

/ *顺序栈出栈*/
 int Pop(SeqStack *S,datatype *x)
{
    */  将栈S的栈顶元素弹出,放到x所指的存储空间中 */
	 if(S->top == -1)    / *栈为空*/
	     return 0;
	 else
 	{ 
 		*x = S->elem[S->top];
	   	S->top--;    /* 修改栈顶指针 */
	 	return 1;
	 }
 } 
*/链栈出栈/*
int Pop_LinkedStack(LinkedStack top, elemtype *x)                    
{	LinkedStackNode * node;
	if(top->next==NULL)
	{
		return 0;
	}
	else
	{
		node=top->next;//将原栈顶数据元素弹出并赋给node
		*x=node->data;//将原栈顶数据元素的数据赋值给x
		top->next=node->next;//top指向链栈中的下一个数据元素
		free (node);//释放原栈顶数据元素所占的空间
		return 1;
	}
}

链栈及顺序栈的对比

两者时间复杂度一样,均为O(1);

对于空间性能,顺序栈需要事先确定一个固定长度,可能会存在空间浪费问题,但它的优势是存取时定位方便,而链栈则要求每个元素都有指针域,这同时也增加了一些内存开销,但对于栈的长度无限制;

如果栈的使用过程中元素变化不可预料,最好使用链栈,反之,如果他的变化在可控范围内,建议使用顺序栈

双栈

两个顺序找stack1,stack2

stack1的栈底为-1,stack2的栈底为MAXSIZE

顺序栈1从左至右依次入栈,top1++

顺序栈2从左至右依次入栈,top2--

栈满条件:top1+1 == top2

双端顺序栈定义

#define MAXSIZE 500
typedef struct
{
    datatype stack[MAXSIZE];
    int top[2];      /*top[0]为左指针,top[1]为右指针*/
}DqStack;

双端顺序栈初始化

int initDupStack(Dqstack *S)
  {
    if((S==(DqStack *)malloc(sizeof(dupsqstack))) == NULL)
        return 0;
    S->top[0] = -1;
    S->top[1] = MAXSIZE; 
    return 1;
  }

双端顺序栈进栈操作

/ *双端顺序栈进栈操作。*/
 int Push(DqStack *S, datatype x, int i)
 {	/ *把数据元素x压入i号堆栈*/
     if(S->top[0]+1==S->top[1])    / *栈已满*/
        return 0;
     switch(i)
     {
         case 0:
             S->top[0]++;	
             S->Stack[S->top[0]]=x;	
             break; /*top[0]为左指针*/
         case 1:
             S->top[1]--;	
             S->Stack[S->top[1]]=x;	
             break; /*top[1]为右指针*/
         default:  / *参数错误*/
             return 0;
     }
     return 1;
 } 

双端顺序栈出栈操作

/ *双端顺序栈出栈操作。*/
 int Pop(DqStack *S,datatype *x,int i)
{	/* 从i 号堆栈中弹出栈顶元素并送到x中 */
     switch(i)
     {
         case 0:
             if(S->top[0]==-1)  return 0;
             *x=S->Stack[S->top[0]];   
             S->top[0]--;	
             break;
         case 1:
             if(S->top[1]==MAXSIZE)  return(FALSE);
             *x=S->Stack[S->top[1]];	
             S->top[1]++;	
             break;
         default:
             return 0;
     }
     return 1;
 } 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值