前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >数据结构基础(四).栈

数据结构基础(四).栈

作者头像
franket
发布2021-09-16 10:05:53
2890
发布2021-09-16 10:05:53
举报
文章被收录于专栏:技术杂记技术杂记

前言

线性表 是一种应用广泛和最为基础的数据结构

线性表的特征:对非空表,a(0)是表头,无前驱;a(n-1)是表尾,无后继;其它的每个元素a(i)有且仅有一个直接前驱a(i-1)和一个直接后继a(i+1)

线性表在计算机存储器中的表示一般有两种形式,一种是 顺序映象,一种是 链式映象

有一个网站 VisuAlgo 能将数据结构进行可视化展示

这里分享一下我在学习线性表过程中的一些笔记,前面一篇用C语言实现了一个简单的 双链表,这里用C语言实现一个简单的


概要


栈是限制在一端进行插入操作和删除操作的线性表,允许进行操作的一端称为“栈顶”,另一固定端称为“栈底”,当栈中没有元素时称为“空栈”,特点是后进先出(LIFO)

Tip: 栈是线性表的一种特殊形式

Note: 也有将 称为 堆栈 的,但其实 在计算机里是代表不同的两种存储机制

线性表在计算机存储器中的表示一般有两种形式,一种是 顺序映象,一种是 链式映象,因此栈也可以使用这两种方式来实现,顺序表实现的局限性在于,空间大小固定,容易溢出,也就是所谓的 stack overflow , 有一个知名的技术知识问答平台就是以此命名的,估计猴子们看到这个会油然一种亲切感

这里我使用单链表不带表头的方式,实现一个简单的栈


代码示例

代码语言:javascript
复制
#include <stdio.h>
#include <malloc.h>

typedef struct stack //创建一个栈结构
{
  int score;
  struct stack *next; //节点里只用包含当前节点的值和,下一节点的位置
}ST,*SP,**SPP; //重命名栈节点结构类型为ST,指针为SP,指针的指针为SPP(第一次用这种高级玩法)

int push(SPP tpp,int score) //入栈操作,注意第一个参数为节点指针的指针
{
  SP newnode=NULL;
  if(NULL != *tpp) //不为空的情况下创建新节点,赋值,并且置于栈顶
  {
    newnode=(SP)malloc(sizeof(ST)); //动态申请内存,创建节点
    if(NULL == newnode)  //进行判断,申请内存失败则提醒并且返回
    {
      printf("push error:no enough memory!\n");
      return -1;
    }
    newnode->score=score;
    newnode->next=*tpp; //置于栈顶
    *tpp=newnode; //将栈顶进行更新
    return 0;
  }
  else //为空的情况下,就创建第一个栈节点
  {
    *tpp=(SP)malloc(sizeof(ST)); //动态申请内存,创建节点
    if(NULL == *tpp)  //进行判断,申请内存失败则提醒并且返回
    {
      printf("error:no enough memory!\n");
      return -1;
    }
    (*tpp)->score=score;
    (*tpp)->next=NULL; //初始化栈底
    return 0;
  }
}

int pop(SPP tpp) //出栈操作,注意第一个参数为节点指针的指针
{
  SP sp=NULL;
  int x=0;

  if(NULL != *tpp) //进行判断,是否为空,不为空则返回栈顶的值,并且销毁节点,更新栈顶
  {
    x = (*tpp)->score; //将栈顶的值进行保存
    sp=*tpp; //这里要借用一个结构体指针临时存放一下栈顶位置
    *tpp = sp->next; //更新栈顶位置
    free(sp); //对原来栈顶进行销毁
    return x; //返回栈顶的值
  }
  else //为空则提醒,并且返回
  {
    printf("pop error:this is a empty stack!\n");
    return -1;
  }  
}

int count(SP top) //计算堆栈元素个数
{
  int i=0; 
  if(NULL != top) 
  {
    for(i=0;top;top=top->next)i++; // the same as : i=1;while(top=top->next)i++; 有多种写法时,可以选用一种最为简洁的形式
    return i;
  }
  else return i;
}

int clear(SPP tpp) //清空栈
{
  if(NULL != *tpp)
  {
    while(*tpp)pop(tpp); //只用循环弹出,直到为空,然后提示退出
    printf("this stack has been clean\n");
    return 0;
  }
  else //本来为空的时候,直接提示退出
  {
    printf("this is an empty stack\n");
    return 0;
  }
}

int show(SP top) //打印所有栈元素
{
  for(;top;top=top->next)printf("(%d)",top->score);
  printf("\n");
  return 0;
}



int main()
{
  SP top=NULL; //这个地方一定要赋初值为NULL,否则会有bug,因为对于是否为栈底的判断依据来源于此
  printf("push 50,80,70,90,100 into stack\n");
  push(&top,50);
  push(&top,80);
  push(&top,70);
  push(&top,90);
  push(&top,100); //压栈测试
  printf("show all nodes in stack\n");
  show(top); //打印测试
  printf("the total count is: %d\n",count(top));
  printf("pop stack\n");
  printf("%d\n",pop(&top)); //出栈测试
  show(top);
  printf("the total count is: %d\n",count(top)); //计数测试
  printf("pop stack\n");
  printf("%d\n",pop(&top));
  show(top);
  printf("the total count is: %d\n",count(top));
  printf("pop stack twice\n");
  printf("%d\n",pop(&top));
  printf("%d\n",pop(&top)); //出栈测试
  printf("clear stack\n"); //清栈测试
  clear(&top);
  printf("pop stack twice\n"); 
  printf("%d\n",pop(&top));
  printf("%d\n",pop(&top)); //对空栈进行出栈测试
  return 0;
}

编译执行

代码语言:javascript
复制
emacs@ubuntu:~/c$ alias gtc
alias gtc='gcc -Wall -g -o'
emacs@ubuntu:~/c$ gtc stack.x  stack.c
emacs@ubuntu:~/c$ ./stack.x 
push 50,80,70,90,100 into stack
show all nodes in stack
(100)(90)(70)(80)(50)
the total count is: 5
pop stack
100
(90)(70)(80)(50)
the total count is: 4
pop stack
90
(70)(80)(50)
the total count is: 3
pop stack twice
70
80
clear stack
this stack has been clean
pop stack twice
pop error:this is a empty stack!
-1
pop error:this is a empty stack!
-1
emacs@ubuntu:~/c$

原文地址

本文系转载,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文系转载前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 前言
  • 概要
      • 代码示例
      领券
      问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档