栈的实现(c语言)

栈的定义

        栈作为一种数据结构是遵循先入后出的原则只能在同一端进行输入和输出。而允许进行插入和删除操作的一端称为栈顶,另一端为栈底 ;栈底固定,而栈顶浮动;栈中元素个数为零时称为空栈。栈的插入数据被称为入栈,取出数据则是为出栈。

栈的示意图,如图所示:

请添加图片描述

栈的存储方式

        栈的存储方式分为链式栈和顺序栈。

       首先介绍的是顺序栈,它是利用一组地址连续的存储单元存放自栈底到栈顶的数据元素

       顺序栈的定义方式为:

     ```c

typedef int ElemType;
typedef struct Line{
ElemType data[MAXSIZE];
int top;
}Line,*S_stack;
```

       而采用链式存储的栈则称之为链栈,通常是使用单链表来进行操作,所以不存在什么栈满溢出这类的问题。

       链式栈的定义方式为:

typedef struct Snode{
         Elemtype data;
         struct node *next;
}node,*Snode;
typedef struct stack{
     Snode top;
    int count;
}stack,*Lstack;

顺序栈的基本操作

栈的初始

      栈初始化的栈顶指针可以设置为s->top=0或者-1,本文中设置的是-1。

S_stack Init_Stack(){
  S_stack s=(S_stack) malloc(sizeof(Line));
  s->top=-1;
    return s;
}

栈的判空

bool Empty(S_stack S){
    if(S.top == -1){
        return true;
    }else{
        return false;
    }
}

进栈操作

    因为初始值设置的是-1,所以在stack->top=-1,所以每次在进栈的时候都要加一。
在这里插入图片描述

ElemType push(S_stack stack,ElemType* elemType){
    if(stack==NULL||stack->top>MAXSIZE){
        return ERROR;
    }
    stack->top++;
    stack->data[stack->top]=*elemType;
    return OK;
}

出栈操作

在这里插入图片描述

  出栈则是先取出数据,再将顶指针减一。

ElemType pop(S_stack stack,ElemType *elemType){
    if(stack==NULL){
        return ERROR;
        }

    *elemType=stack->data[stack->top];
    stack->top--;
    return OK;
}

遍历栈

接收顶指针的位置只要大于0就说明还有数据就会一直遍历,直到小于0才会停止。

ElemType Print_Stack(S_stack stack){
    int x;
    if(stack==NULL){
        return ERROR;
    }
   x=stack->top;
    while (x>=0){
        printf("%d  ",stack->data[x]);
        x--;
    }
    return OK;
}

销毁栈

void DestroyStack(SqStack &S){
    S.top = -1;
}

插入多个数据

在栈定义的内存中,可以一直插入数据,如果像停止则按Ctrl+D

S_stack S_stackHead(S_stack stack){
    int x;
    if(stack==NULL||stack->top>MAXSIZE){
        return ERROR;
    }
    while (scanf("%d",&x)!=EOF){
        stack->top++;
        stack->data[stack->top]=x;
    }
    return stack;
}

完整代码

#include "stdlib.h"
#include "stdio.h"
#define MAXSIZE 100
#define OK 1
#define ERROR 0
typedef int ElemType;
typedef struct Line{
  ElemType data[MAXSIZE];
  int top;
}Line,*S_stack;
S_stack Init_Stack(){
  S_stack s=(S_stack) malloc(sizeof(Line));
  s->top=-1;
    return s;
}
S_stack S_stackHead(S_stack stack){
    int x;
    if(stack==NULL||stack->top>MAXSIZE){
        return ERROR;
    }
    while (scanf("%d",&x)!=EOF){
        stack->top++;
        stack->data[stack->top]=x;
    }
    return stack;
}
ElemType Print_Stack(S_stack stack){
    int x;
    if(stack==NULL){
        return ERROR;
    }
   x=stack->top;
    while (x>=0){
        printf("%d  ",stack->data[x]);
        x--;
    }
    return OK;
}
ElemType push(S_stack stack,ElemType* elemType){
    if(stack==NULL||stack->top>MAXSIZE){
        return ERROR;
    }
    stack->top++;
    stack->data[stack->top]=*elemType;
    return OK;
}
ElemType pop(S_stack stack,ElemType *elemType){
    if(stack==NULL){
        return ERROR;
        }

    *elemType=stack->data[stack->top];
    stack->data[stack->top]=  NULL;
    stack->top--;
    return OK;
}

链式栈的基本操作

链栈的初始化

Lstack InitStack(){
    Lstack p;
    //p = new Link_Stack;
    p=(Lstack)malloc(sizeof(stack));
    if(p==NULL){
        printf("创建失败");
        exit(0);
    }
    p->count = 0;
    p->top = NULL;
    return p;
}

遍历链栈

因为定义的栈是节点和个数,所以要先获取栈内的节点,之后放方便遍历整个栈。

void Print_stack(Lstack l){
    if (l->top == NULL)
    {
        printf("");
        printf("错误:栈为空");
        exit(0) ;
    }
    Snode  snode=l->top;
    while (snode!=NULL){
        printf("\n%d \n",snode->data);
       snode=snode->next;
    }
}

入栈操作

status push(Lstack stack,Elemtype e){
    if(stack==NULL){
        return NULL;
    }
    node *L=(node*) malloc(sizeof(node));
    L->data=e;
    L->next=stack->top;
    stack->top=L;
    stack->count++;
    printf("\n入栈成功");
    return OK;
}

出栈操作

status pop(Lstack stack,Elemtype *e){
    if(stack==NULL){
        printf("栈为空");
        return ERORR;
    }
    *e=stack->top->data;
    node* n;
    n=stack->top;
    stack->top=stack->top->next;
    free(n);
    stack->count--;
    printf("\n出栈成功");
    return OK;
}

判空操作

bool isEmpty(Lstack stack){
    if(stack->count==0){
        return true;
    } else{
        return false;
    }
}

获取栈的个数

Elemtype getCount(Lstack stack){
    return stack->count;
}

完整代码

/**
 * 链栈表
 *
 */
#include <stdio.h>
#include <stdlib.h>
#include <stdbool.h>

#define OK 1
#define ERORR 0
typedef int status;
typedef int  Elemtype;
typedef struct Snode{
         Elemtype data;
         struct node *next;
}node,*Snode;
typedef struct stack{
     Snode top;
    int count;
}stack,*Lstack;
Lstack InitStack(){
    Lstack p;
    //p = new Link_Stack;
    p=(Lstack)malloc(sizeof(stack));
    if(p==NULL){
        printf("创建失败");
        exit(0);
    }
    p->count = 0;
    p->top = NULL;
    return p;
}
void Print_stack(Lstack l){
    if (l->top == NULL)
    {
        printf("");
        printf("错误:栈为空");
        exit(0) ;
    }
    Snode  snode=l->top;
    while (snode!=NULL){
        printf("\n%d \n",snode->data);
       snode=snode->next;
    }
}


status push(Lstack stack,Elemtype e){
    if(stack==NULL){
        return NULL;
    }
    node *L=(node*) malloc(sizeof(node));
    L->data=e;
    L->next=stack->top;
    stack->top=L;
    stack->count++;
    printf("\n入栈成功");
    return OK;
}

status pop(Lstack stack,Elemtype *e){
    if(stack==NULL){
        printf("栈为空");
        return ERORR;
    }
    *e=stack->top->data;
    node* n;
    n=stack->top;
    stack->top=stack->top->next;
    free(n);
    stack->count--;
    printf("\n出栈成功");
    return OK;
}
bool isEmpty(Lstack stack){
    if(stack->count==0){
        return true;
    } else{
        return false;
    }
}

Elemtype getCount(Lstack stack){
    return stack->count;
}
int main(){
    int x;
    Lstack l=  InitStack();
    push(l,2);
    push(l,3);
    push(l,4);
//    bool a= isempty(l);
    Print_stack(l);
    pop(l,&x);
    printf("\nx的值%d",x);
    Print_stack(l);
}
  • 0
    点赞
  • 12
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值