数据结构——栈(顺序栈,链栈)

栈的定义

是一种只能在一端进行插入或删除操作的线性表。 表中允许进行插入、删除作的一端称为栈顶.栈顶的当前位置是动态的,栈顶的当前位置由一个称为栈顶指针的位置指示器指示。表的另一端称为栈底。当栈中没有数据元素时,称为空栈。栈的插入操作通常称为进栈或入栈,栈的删除操作通 常称为退栈或出栈。

特点:是“后进先出”,即后进栈的元素先出栈。



栈的顺序存储结构

顺序栈:利用顺序存储方式实现的栈称为顺序栈

先来定义一下顺序栈的数据类型

typedef struct {  
    int data[maxsize];    
    int top; //栈顶指针
} SqStack;

栈的几种基本运算如下:

  1. InitStack(&s):初始化栈。构造一个空栈s。

    void InitStack(SqStack *&s){
      s=(SqStack*)malloc(sizeof(SqStack));
        s->top = -1;//开始是空栈
    }
    // 栈空条件:top=-1  
    //栈满条件:top=MaxSize-1  
    //进栈e操作:top++; 将e放在top处  
    //退栈操作:从top处取出元素e; top--;
    
    
  2. DestroyStack(&s):销毁栈。释放栈s占用的存储空 间。

    void ClearStack(SqStack *&s){
    	free(s);
    }
    
  3. StackEmpty(s):判断栈是否为空:若栈s为空,则 返回真;否则返回假。

    bool IsEmpty(SqStack *s){
    	return (s->top==-1); 
    }
    
  4. Push(&S,e):进栈。将元素e插入到栈s中作为栈顶 元素。
    在栈不满的条件下,先将栈指针增1,然后在该位置上插 入元素e

    bool Push(SqStack *&s,int e){
        if (s->top==maxsize-1)
            return false;//已经满了
        else{
            s->top++;
            s->data[s->top]=e;
            return true;
        }
    }
    
  5. Pop(&s,&e):出栈。从栈s中退出栈顶元素,并将 其值赋给e。

    bool Pop(SqStack *&s, int &e){
        if(s->top==-1)
            return false;//空栈
        else{
            e=s->data[s->top];
            s->top--;
            return true;
        }
    }
    
  6. GetTop(s,&e):取栈顶元素。返回当前的栈顶元素, 并将其值赋给e

    bool GetTop(SqStack *s,int &e) {
        if (s->top==-1) //栈为空的情况,即栈下溢出       
            return false;
        e=s->data[s->top]; //取栈顶指针元素的元素
        return true;
    }
    

看完上面的封装好的函数,我们把代码整合在一起操作一下

#include<stdio.h>
#include<string.h>
#include<stdlib.h>
#include<iostream>
const int maxsize = 10;
typedef struct {  
    int data[maxsize];    
    int top; //栈顶指针
} SqStack;
void InitStack(SqStack *&s){
    s=(SqStack*)malloc(sizeof(SqStack));
    s->top = -1;//开始是空栈
}
// 栈空条件:top=-1  
//栈满条件:top=MaxSize-1
  
void ClearStack(SqStack *&s){ free(s); 
bool IsEmpty(SqStack *s){ return (s->top==-1); }

bool Push(SqStack *&s,int e){
    if (s->top==maxsize-1)
        return false;//已经满了
    else{
        s->top++;
        s->data[s->top]=e;
        return true;
    }
}

bool Pop(SqStack *&s, int &e){
    if(s->top==-1)
        return false;//空栈
    else{
        e=s->data[s->top];
        s->top--;
        return true;
    }
}

bool GetTop(SqStack *s,int &e) {
    if (s->top==-1) //栈为空的情况,即栈下溢出       
        return false;
    e=s->data[s->top]; //取栈顶指针元素的元素
    return true;
}

int main(){
	SqStack *z;
	int s,p,e;
	int a[]={12,5,8,1,7,5,4,6,20};
	InitStack(z);
	if(IsEmpty(z))
		s=0;
	else
		s=1;
	printf("%d\n",s);
	for(int i=0;i<9;i++)
	Push(z,a[i]);
	
	GetTop(z,e);
	printf("%d\n",e);
	
	for(int i=0;i<2;i++){
		Pop(z,e);
		printf("%d\n",e);	
	}
}


栈的链式存储结构

链栈**:利用单链表存储方式实现的栈称为顺序栈

链栈的优点是不存在栈满上溢的情况

先来定义一下链栈的数据类型

typedef struct linknode {  
 int data; //数据域   
 struct linknode *next; //指针域 
 } LiStack;

栈的几种基本运算如下:

  1. InitStack(&s):初始化栈。构造一个空栈s。

    void InitStack(LiStack *&s){
       s=(LiStack*)malloc(sizeof(LiStack));
        s->next = NULL;
    }
    //栈空条件:s->next=NULL 
    //栈满条件:不考虑 
    
    
  2. DestroyStack(&s):销毁栈。释放栈s占用的存储空 间。

    void ClearStack(LiStack *&s){
        LiStack *p=s,*q=s->next;
        while(q!=NULL){
         free(p);
         p=q;
         q=q->next;
         }
         free(p);//把尾节
      }  
    
    
  3. DestroyStack(&s):销毁栈。释放栈s占用的存储空 间。

    void ClearStack(LiStack *&s){
    	LiStack *p=s,*q=s->next;
        while(q!=NULL){
            free(p);
            p=q;
            q=q->next;
        }
        free(p);//把尾节点也释放
    }
    
  4. StackEmpty(s):判断栈是否为空:若栈s为空,则 返回真;否则返回假。

    bool IsEmpty(LiStack *s){
    	return (s->next==NULL); 
    }
    
  5. Push(&S,e):进栈。将元素e插入到栈s中作为栈顶 元素。
    在栈不满的条件下,先将栈指针增1,然后在该位置上插 入元素e

    void Push(LiStack *&s,int e){
        LiStack *p;
        p = (LiStack*)malloc(sizeof(LiStack));
        p->data =e;
        p->next = s->next;
        s->next = p;
    }
    
  6. Pop(&s,&e):出栈。从栈s中退出栈顶元素,并将 其值赋给e。

    bool Pop(LiStack *&s, int &e){
        LiStack *p;
        if(s->next==NULL)
            return false;//空栈
        else{
            p=s->next;
            e=p->data;
            s->next = p->next;
            free(p);
            return true;
        }
    }
    
  7. GetTop(s,&e):取栈顶元素。返回当前的栈顶元素, 并将其值赋给e。

    
    bool GetTop(LiStack *s,int &e) {
     if (s->next==NULL) //栈空的情况
          return false;
      e=s->next->data;
      	return true; 
    }
    

一般的多用的是顺序栈,对于链栈的使用不多,链栈具体代码整合于顺序栈类似,这里就不再赘述。

发布了50 篇原创文章 · 获赞 50 · 访问量 2733

猜你喜欢

转载自blog.csdn.net/weixin_45691686/article/details/104806294
今日推荐