Loading [MathJax]/jax/output/CommonHTML/config.js
首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >专栏 >【自考】数据结构第三章,栈、队列、数组,期末不挂科指南,第3篇

【自考】数据结构第三章,栈、队列、数组,期末不挂科指南,第3篇

作者头像
梦想橡皮擦
发布于 2020-02-10 03:01:14
发布于 2020-02-10 03:01:14
1K00
代码可运行
举报
运行总次数:0
代码可运行

学习目标

自考重点、期末考试必过指南,这篇文章让你理解什么是栈、什么是队列、什么是数组

掌握栈、队列的顺序存储结构和链式存储结构

掌握栈、队列的基本操作在顺序存储结构和链式存储结构上的实现

掌握矩阵的压缩存储

今天核心咱们先把栈搞清楚

栈和队列可以看做是特殊的线性表 。它们的特殊性表现在它们的基本运算是线性表运算的子集,它们是运算受限的线性表

栈(Stack)是运算受限的线性表,这种线性表上的插入和删除操作限定在表的一端进行

基本概念

栈顶:允许插入和删除的一端 栈尾:另一端 空栈:不含任何数据元素的栈 栈顶元素:处于栈顶位置的数据元素

书中的例子比较形象

洗盘子,放盘子,每次只能从这一摞盘子的最上面拿走,这就是栈的基本操作

看重点:栈---> ==后进先出(Last In First Out) LIFO 原则 ==

所以栈被称作 后进先出线性表 (后进先出表)

栈的插入和删除运算 分为成为 进栈和 出栈

栈的基本运算
  • 初始化 InitStack(S) 构造一个空栈S
  • 判断栈空 EmptyStack(S) 若栈为空,返回1,否则返回0
  • 进栈Push(S,x) 将元素x插入栈S中
  • 出栈Pop(S) 删除栈顶元素
  • 取栈顶GetTop(S) 返回栈顶元素

栈的顺序实现

这里面有两个小知识点在写代码之前需要掌握

空栈做出栈操作,会出现问题,叫做“下溢” 满栈做进栈操作,会出现问题,叫做“上溢”

接下来我们就用C语言实现一下

初始化一个空栈

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
#include <stdio.h>
#include <stdlib.h>
// 声明顺序栈的容量
const int maxsize = 6;
struct seqtack{
    int *data;  //存储栈中元素的数组
    int top;  // 栈顶下标
};

typedef struct seqtack Seq;

// 初始化操作
Seq init(Seq s){
    printf("初始化函数运行\n");
    s.data = (int*)malloc(maxsize*sizeof(int));//动态分配存储空间
    if(!s.data){
        printf("初始化失败");
        exit(0);
    }
    s.top = 0;
    return s;
}

注意事项

初始化需要动态分配空间,并且需要让top值等于0

判断栈空

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
//判断栈空
int empty(Seq s){
    printf("判断栈空\n");
    if(s.top == 0){
        return 1;
    }
    return 0;
}

这个比较简单了,只需要判断s.top值就可以了

进栈操作

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
//进栈操作
Seq push(Seq s,int x){
    printf("进栈操作\n");
    // 判断栈是否满了
   
    if(s.top==maxsize-1){
        printf("栈满");
        return s;
    }
    else{
        
        printf("正在插入数据%d\n",x);
        s.data[s.top] = x;
        s.top++;
        return s;
    }
    
}

出栈操作

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
//出栈操作
Seq pop(Seq s,int *e){
    if(empty(s)){
        printf("栈空\n");
        exit(0);
    }
    else{
        *e = s.data[s.top-1];
        s.top--;
        return s;
    }
}

进栈和出栈,这部分内容一定要好好的理解,其实也是比较简单的,就是添加元素和删除元素

打印栈中元素与获取栈顶元素

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
// 打印栈中元素
void display(Seq s){
    if(empty(s)){
        printf("栈空\n");
        exit(0);
    }
    else{
        printf("开始打印\n");
        int num = 0;
        while(num < s.top){
            printf("现在的元素是:%d\n",s.data[num++]);
        }
    }
}
// 获取栈顶元素
int gettop(Seq s){
    if(empty(s)){
        exit("栈空\n");
    }
    else{
        return s.data[s.top-1];
    }
}

主函数测试代码

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
int main()
{
    printf("代码运行中\n");
    Seq s ;
    s = init(s);
    
    //插入两个元素
    s = push(s,1);
    s = push(s,2);
    
    display(s);
    int e;
    s = pop(s,&e);
    printf("删除的元素是:%d\n",e);
    
    display(s);
 
    return 0;
}

双栈

书中还提到了双栈,不过这个不是重点了,你要知道的是,双栈的两个栈底分别设置在数组的两端,栈顶分为是top1,top2

两个栈顶在中间相遇,条件为 (top1+1=top2)发生上溢

判断栈空条件呢? 一个是 top=0 另一个是top = maxsize -1 这个要注意一下即可

栈的链接实现

栈的链接实现称为==链栈==。链栈 可以用带头结点的单链表来实现,链栈不用预先考虑容量的大小

链栈将链表头部作为栈顶的一端,可以避免在实现数据“入栈”和“出栈”操作时做大量遍历链表的耗时操作

链表的头部作为栈顶,有如下的好处

  1. 入栈 操作时,只需要将数据从链表的头部插入即可
  2. 出栈 操作时,只需要删除链表头部的首结点即可

结论:链表实际上就是一个只能采用头插法插入或删除的链表

例子:将元素1,2,3,4依次入栈,等价于将各元素采用头插法依次添加到链表中

图片来源网络

完整代码如下

由于比较简单,直接贴上了

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
#include <stdio.h>
#include <stdlib.h>
typedef struct node{
    int data;   //数据域
    struct node *next;   //链域
} LkStk;

//初始化
void init(LkStk *ls){
    printf("初始化操作\n");
    ls = (LkStk *)malloc(sizeof(LkStk)); 
    ls->next = NULL;
}

// 进栈
void push(LkStk *ls,int x){
    printf("进栈操作\n");
    LkStk *temp;
    temp = (LkStk*)malloc(sizeof(LkStk));//给temp新申请一块空间
    temp->data = x;
    temp->next = ls->next;
    ls->next = temp;
    printf("%d进栈成功\n",x);
}
int empty(LkStk *ls){
    if(ls->next ==NULL){
        return 1;
    }
    else return 0;
}

// 出栈
int pop(LkStk *ls){
    LkStk *temp;
    //判断栈是否为空
    if(!empty(ls)){
        temp= ls->next;  // 准备出栈的元素指向ls的下一结点
        ls->next = temp->next;   // 原栈顶的下一个结点称为新的栈顶
        printf("栈顶元素:%d\n",temp->data);
        free(temp); //释放原栈顶的结点空间
        return 1;       
    }
    return 0;
}

int main()
{
    LkStk ls;
    init(&ls);
    
    push(&ls,1);
    push(&ls,2);
    
    pop(&ls);
    pop(&ls);

    return 0;
}

这就是链栈的基本进栈和出栈了,当然,我们还可以获取一下栈顶元素

考试要点

在自考或者期末考试中,容易出现的一种题是手写入栈和出栈 例如

设一个链栈的输入序列为A、B、C,试写出所得到的所有可能的输出序列,即输出出栈操作的数据元素序列

写答案的时候,记住先进后出原则

从A开始写 A进,A出,B进,B出,C进,C出 A进,B进,B出,C进,C出,A出 ... ... 继续写下去就可以了,一定不要出现A进,B进,B出,C进,==A出== 注意,A出不去,A前面有C呢

在来一个例题

如图所示,在栈的输入端元素的输入顺序为A,B,C,D,进栈过程中可以退栈,写出在栈的输出端以A开头和以B开头的所有输出序列。

这个就是把A开头和B开头的都写出来

  1. ABCD、ABDC、ACBD、ACDB、ADCB
  2. BACD、BADC、BCAD、BCDA、BDCA

主要仔细,就能写对,套路就是,先进后出

小结

栈是只能在一端(栈顶)进行插入和删除运算的线性表,具有后进先出特征。

以顺序存储结构实现的栈称为顺序栈,以链式存储结构实现的栈称为链栈。

顺序栈需要预先定义栈的大小,在难以估计栈的大小时,可以采用链栈,链栈是用单链表实现。一般地,将栈顶设在链表的表头一端,栈底设置在链表的表尾。栈适合与具有后进先出特征的问题。

如程序实现递归,函数调用等。

本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
原始发表:2019-12-31 ,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

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

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
暂无评论
推荐阅读
编辑精选文章
换一批
数据结构 第三章栈和队列
假设在周末舞会上,男士和女士们分别进入舞厅,各自排成一队。跳舞开始,依次从男队和女队队头各出一人配成舞伴,若两队初始人数不同,则较长那一队未配对者等待下一轮舞曲。现要求写一算法模拟上述舞伴配对问题。 你需要用队列操作实现上述算法。请完成下面5个函数的操作。
十二惊惶
2024/02/28
3910
期末复习之数据结构 第3章 栈和队列
五:写出下列程序段的输出结果(栈的元素类型SElem Type为char)。 1.void main( ){ Stack S; Char x,y; InitStack(S); X=’c’;y=’k’; Push(S,x); Push(S,’a’); Push(S,y); Pop(S,x); Push(S,’t’); Push(S,x); Pop(S,x); Push(S,’s’); while(!StackEmpty(S)){ Pop(S,y);printf(y); }; Printf(x); } 答:输出为“stack”。 2.【严题集3.12②】写出下列程序段的输出结果(队列中的元素类型QElem Type为char)。 void main( ){ Queue Q; Init Queue (Q); Char x=’e’; y=’c’; EnQueue (Q,’h’); EnQueue (Q,’r’); EnQueue (Q, y); DeQueue (Q,x); EnQueue (Q,x); DeQueue (Q,x); EnQueue (Q,’a’); while(!QueueEmpty(Q)){ DeQueue (Q,y);printf(y); }; Printf(x); } 答:输出为“char”。 3.【严题集3.13②】简述以下算法的功能(栈和队列的元素类型均为int)。 void algo3(Queue &Q){ Stack S; int d; InitStack(S); while(!QueueEmpty(Q)){ DeQueue (Q,d); Push(S,d); }; while(!StackEmpty(S)){ Pop(S,d); EnQueue (Q,d); } } 答:该算法的功能是:利用堆栈做辅助,将队列中的数据元素进行逆置。
henu_Newxc03
2021/12/28
7750
期末复习之数据结构 第3章 栈和队列
数据结构 第三章 栈和队列
栈顶:通常将表中允许进行插入、删除操作的一端称为栈顶 (Top),因此栈顶的当前位置是动态变化的,它由一个称为栈顶指针的位置指示器指示。
Twcat_tree
2022/11/29
6870
数据结构 第三章 栈和队列
数据结构(四):栈
栈是只能在一端进行插入和删除操作的线性表。表中允许进行插入、删除操作的一端称为栈顶。栈顶的位置是动态的,由一个称为栈顶指针的位置指示器指示。表的另一端称为栈底。
渔父歌
2018/12/14
8010
数据结构与算法:栈
在应用软件中,栈的应用非常普遍,比如使用浏览器上网时,会有一个后退键,点击后可以按访问顺序的逆序加载浏览过的网页
用户11029103
2024/03/19
1530
数据结构与算法:栈
2024重生之回溯数据结构与算法系列学习(6)【无论是王道考研人还是IKUN都能包会的;不然别给我家鸽鸽丢脸好嘛?】
https://netsecur-cloud-ljs.blog.csdn.net/article/details/142311773 ​​​​​​​ ​​​​​​​ ​​​​​​​ ​​​​​​​ ​​​​​​​
盛透侧视攻城狮
2024/10/22
1250
2024重生之回溯数据结构与算法系列学习(6)【无论是王道考研人还是IKUN都能包会的;不然别给我家鸽鸽丢脸好嘛?】
算法与数据结构——顺序存储栈和链式存储栈
先上官方定义:栈(stack)又名堆栈,它是一种运算受限的线性表。限定仅在表尾进行插入和删除操作的线性表。这一端被称为栈顶,相对地,把另一端称为栈底。
CC老师
2022/01/12
4760
算法与数据结构——顺序存储栈和链式存储栈
数据结构-栈
该文介绍了数据结构中的栈和链式栈,包括它们的定义、性质、操作和实现。
chaibubble
2018/01/02
7530
数据结构-栈
【图解数据结构】 栈&队列
1.栈 1.1栈的定义 栈(stack)是限定在表尾进行插入和删除的操作的线性表。 我们把允许插入和删除的一端称为栈顶(top),另一端称为栈底(bottom),不包含任何数据元素的栈称为空栈。栈又称
撸码那些事
2018/06/21
1.4K0
数据结构01-线性结构-链表栈队列-栈篇
本系列为C++数据结构系列,会介绍 线性结构,简单树,特殊树,简单图等。本文为线性结构部分。
IT从业者张某某
2023/10/16
1840
数据结构01-线性结构-链表栈队列-栈篇
【数据结构】什么是栈?
生活中类似于栈"先进后出"概念的东西很多,如我们平常用的抽纸,装羽毛球的球筒,装子弹的弹夹等.
修修修也
2024/04/01
1280
【数据结构】什么是栈?
浅谈栈与队列
栈(Stack):是只允许在一端进行插入或删除的线性表。首先栈是一种线性表,但限定这种线性表只能在某一端进行插入和删除操作。
一条晒干的咸鱼
2024/11/19
950
浅谈栈与队列
数据结构 | 栈
01 栈的定义 栈(Stack)是限定仅在表尾进行插入和删除操作的线性表。 我们把允许插入和删除的一端称为栈顶(top),另一端称为栈底(bottom),不含任何数据元素的栈称为空栈。栈又称为后进先出(Last In First Out)的线性表,简称 LIFO 结构。 从上面这两段话,可以确定:首先栈是一个线性表,也就是说,栈元素具有线性关系,即前驱后继关系,只不过它是一种特殊的线性表。定义中说在线性表的表尾进行插入和删除操作,这里表尾是指栈顶,而不是栈底。 栈的插入操作,叫做进栈,也叫压栈、入栈。 栈
用户1332428
2018/03/08
7440
数据结构 | 栈
栈的基本操作
栈(stack)又名堆栈,它是一种运算受限的线性表。限定仅在表尾进行插入和删除操作的线性表。这一端被称为栈顶,相对地,把另一端称为栈底。向一个栈插入新元素又称作进栈、入栈或压栈,它是把新元素放到栈顶元素的上面,使之成为新的栈顶元素;从一个栈删除元素又称作出栈或退栈,它是把栈顶元素删除掉,使其相邻的元素成为新的栈顶元素。 栈是只能在表的一端进行数据存取的数据结构。我们来看图示。其实还是很好理解的。
兰舟千帆
2022/07/16
3960
栈的基本操作
【数据结构】栈和队列的定义与实现
栈:一种特殊的线性表,其只允许在固定的一端进行插入和删除元素操作。进行数据插入和删除操作的一端称为栈顶,另一端称为栈底。栈中的数据元素遵守后进先出LIFO(Last In First Out)的原则。
HABuo
2024/11/19
1270
【数据结构】栈和队列的定义与实现
数据结构学习笔记——栈
我们允许插入和删除的一端称为栈顶(top),另一端称为栈底(bottom),不含任何数据元素的栈称为空栈。
蜻蜓队长
2018/08/03
2820
数据结构学习笔记——栈
数据结构学习—栈
栈的定义 限定在表尾作插入、删除操作的线性表,表中允许进行插入、删除操作的一端称为栈顶(Top),表的另一端称为栈底(Bottom)。 顺序栈 用顺序存储结构实现的栈,即利用一组地址连续的存储单元一次存放自栈底到栈顶的数据元素,同时由于栈的操作的特殊性,还必须设一个位置指针top(栈顶指针)来动态的指示栈顶元素在顺序栈中的位置。(通常以top=-1表示空栈) #include <stdio.h> #define OK 1 #define ERROR 0 #define TRUE 1 #define
用户5513909
2023/04/25
1670
数据结构学习—栈
数据结构资料汇编:栈
以上两种定义,本质上是一样的。在第一种定义中,栈 s 的指针 s.base 在对栈进行操作时不变化,因此可以用它指向栈的数据元素。
老齐
2023/03/02
5400
数据结构资料汇编:栈
数据结构(三)-- 栈、队列
栈(stack)又名堆栈,它是一种运算受限的线性表。限定仅在表尾进行插入和删除操作的线性表。这一端被称为栈顶,相对地,把另一端称为栈底。向一个栈插入新元素又称作进栈、入栈或压栈,它是把新元素放到栈顶元素的上面,使之成为新的栈顶元素;从一个栈删除元素又称作出栈或退栈,它是把栈顶元素删除掉,使其相邻的元素成为新的栈顶元素。
看、未来
2021/09/18
2870
来测试一下你对数据结构中的栈和队列的了解有多少?
选择题 1.向一个栈顶指针为top的链栈中插入一个结点s,执行( )。 A.top.next=s; B.s.next=top.next ;top.next=s; C.s.next=top;top=s; D.s.next=top; top=top.next ; 2.栈通常采用的两种存储结构为( )。 A.散列方式和索引方式 B.顺序存储结构和链式存储结构 C.链表存储结构和数组 D.线性存储结构和非线性存储结构 3.一个栈的入栈序列是a,b,c,d,e,则栈的输出序列不可能是( )。 A.e,d,c,b,a
Java学习
2018/04/17
1.3K0
相关推荐
数据结构 第三章栈和队列
更多 >
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档
本文部分代码块支持一键运行,欢迎体验
本文部分代码块支持一键运行,欢迎体验