数据结构与算法基础(王卓)(11):栈的定义及其基础操作(顺序表和链表的初始化、求长度,是否为空,清空和销毁、出栈、压栈)

news2024/9/21 4:32:10

 栈的定义:

stack:一堆,一摞;堆;垛;


顺序栈和链栈的设计参考:

数据结构与算法基础(王卓)(7):小结:关于链表和线性表的定义及操作_宇 -Yu的博客-CSDN博客


顺序栈:


前置条件:

(这里写的是线性表的构造形式,也可以写成链表的构造形式)

//基于线性表的定义所做的更改
#include<iostream>
using namespace std;
#include<stdlib.h>//存放exit
#include<math.h>//OVERFLOW,exit

#define TRUE        1
#define FALSE       0
#define OK          1
#define ERROR       0
#define INFEASIBLE  -1
//#define OVERFLOW   -2   

#define MAXlength 100  
//可按需修改,PPT中写的是MAXlength

struct Poly
{
	float p;
	int e;

	bool operator==(Poly t)
	{
		return t.p == p && t.e == e;
	}
	bool operator!=(Poly t)
	{
		return t.p != p || t.e != e;
	}
};

struct Sqlist
{
	Poly* elem;
	int length;
};

typedef int Status; 
typedef Poly Elemtype;
typedef Elemtype SElemType;
//注意:这一段必须写在调用SElemType类型及其指针之前

struct SqStack
{
	SElemType* base; //栈底指针  
	SElemType* top;//栈顶指针
	int stacksize; //栈可用最大容量
};

初始化:

Status InitStack(SqStack& S)//构造一个空栈
{
	S.base = new SElemType[MAXlength];
	//或
	//S.base = (SElemType*)malloc(MAXlength * sizeof(SElemType));
	if (!S.base) exit(OVERFLOW);// 存储分配失败
	S.top = S.base;
	//栈顶指针等于栈底指针
	S.stacksize = MAXlength;
	return true;
}

简单操作:(求长度,是否为空,清空和销毁)

Status StackEmpty(SqStack S)
{
	// 若栈为空,返回TRUE;否则返回FALSE 
	if (S.top == S.base)
		return TRUE;
	else
		return FALSE;
}

int StackLength(SqStack S)
{
	return S.top - S.base;
}

Status ClearStack(SqStack S)//清空顺序栈
{
	if (S.base)
		S.top = S.base;
	return OK;
}


Status DestroyStack(SqStack& S)//销毁
{
	if (S.base)
	{
		delete S.base;
		S.stacksize = 0;
		S.base = S.top = NULL;
	}
	return OK;
}

在这里,我们很容易产生这样的疑问:

关于清空和销毁,我们不是应该把元素一个一个置为NULL吗???

这里销毁和清空改变的只是指向这个位置的指针的值,可是没有把位置的内容置空(null)啊??

实际原因解释如下:

清空:


这里我们其实只是让(将)栈回归到(置于)空栈的状态(两指针指向同一栈点)

至于栈的内容,清不清除其实都无所谓:

因为只要我们后面在写入元素,前面放在栈中没有被消除的元素自然都会被覆盖


销毁:


直接销毁base指针,这里我们或许会觉得:

你只不过是销毁base指针而已,你凭啥就说这样操作我们能实现销毁整个栈的内容和内存?

而事实上他确实办到了,至于原因,我们可以去看看该表的初始化操作:

在给该表初始化时,我们采用的操作是给base指针开辟内存空间:

    S.base = new SElemType[MAXlength];

所以只要我们把base指针销毁就可以实现销毁整个栈的内容和内存的操作:

delete操作销毁了base指针内部的内容同时也销毁了以base指针作为头指针的整个栈的内存空间


压栈:

程序设计流程:


程序:

Status Push(SqStack& S, SElemType e)
{
	if (S.top-S.base==S.stacksize)//不是MAXlength
		return OVERFLOW;
	*S.top = e;
	S.top++;
	//也可以写成:
	//*S.top++ = e;
	return true;
}

ISSUES:


(1):

注意,这里栈满的语句写的是:

    if (S.top-S.base==S.stacksize)

其中的 S.stacksize 不能写 MAXlength


(2):

关于 *S.top++ = e;    的优先级问题:

自增(算术运算符)的优先级大于赋值运算符

所以理论上说,这里应该是先自增,后运算

但是(然而),这里我们写的语句用的是:*S.top++

也就是说:在等到该语句中,所有其他操作都执行完成以后,再执行自增操作

所以才等价于先赋值,再自增


出栈:

程序设计流程:


程序:

Status Pop(SqStack& S, SElemType& e)
//若栈不空,则删除S的栈顶元素,用e返回其值,并返回OK;	否则返回ERROR
{
	if (S.top == S.base) // 等价于 if(StackEmpty(S))
		return UNDERFLOW;//ERROR;
	e = *S.top;
	S.top--;
	//e = *--S.top;
	return true;
}

同样的,这里先赋值,后自减;

这里不再赘述


链栈:

前置条件:

//基于链表的定义所做的更改
#include<iostream>
using namespace std;
#include<stdlib.h>//存放exit

#define TRUE        1
#define FALSE       0
#define OK          1
#define ERROR       0
#define INFEASIBLE  -1
//#define OVERFLOW   -2   

#define MAXlength 100  //初始大小为100,可按需修改

struct K//Poly
{
    float a;
    int b;
    string c;
    bool operator==(K& t)
    {
        return t.a == a && t.b == b;
        //&& t.c = c;
    }
    bool operator!=(K& t)
    {
        return t.a != a || t.b != b;
        //|| t.c = c;
    }
};
typedef K Elemtype;         //函数调用状态

struct Lnode
    //node:结; 结点;
{
    Elemtype data;
    Lnode* next;
};
typedef Lnode* LinkList;

typedef int Status; 
typedef K Elemtype;
typedef Elemtype SElemType;
//注意:这一段必须写在调用SElemType类型及其指针之前

struct StackNode
{
    SElemType data;
    StackNode* next;
};
typedef StackNode *LinkStack;
LinkStack S;

其中:(模块构造解析) 

SElemType:Poly(复合)型

top,base:SElemType型指针

 另外,在这里我们需要注意,定义结构体时可以实现嵌套自身,本质上就像:

#include<iostream>
using namespace std;

struct S
{
    int data;
    S* next;
};

int main()
{

}

简单操作:(初始化、是否为空、取栈顶元素)

int InitStack(LinkStack& S) 
{
    //构造一个空栈,栈顶指针置为空
    S = NULL;
    return OK;
}

Status StackEmpty(LinkStack S)
{
    if (S == NULL)
        return TRUE;
    else return FALSE;
}

SElemType GetTop(LinkStack S)
{
    if (S != NULL)
        return S->data;
}


入栈:

Status Push(LinkStack& S, SElemType e)
{
    StackNode* p = new StackNode;
    p->data = e;
    p->next = S;

    S = p;

    return true;
}

出栈:


我写的:

Status Pop(LinkStack& S, SElemType e)
{
    LinkStack p = S;
    e = p->data;
    S = p->next;
    delete p;
    return true;
}

参考PPT,我们可以发现,做出如下改动会更好更严谨:

加上语句:
    if (S == NULL) return ERROR;

 

返回的e为引用类型

最终版:

Status Pop(LinkStack& S, SElemType &e)
{
    if (S == NULL) return ERROR;
    LinkStack p = S;
    e = p->data;
    S = p->next;
    delete p;
    return true;
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/359803.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

【免费教程】 SWMM在城市水环境治理中的应用及案例分析

SWMMSWMM&#xff08;storm water management model&#xff0c;暴雨洪水管理模型&#xff09;是一个动态的降水-径流模拟模型&#xff0c;主要用于模拟城市某一单一降水事件或长期的水量和水质模拟。EPA&#xff08;Environmental Protection Agency&#xff0c;环境保护署&am…

QTCreator 设置编码格式

显示文件编码格式 选择“工具>首选项>文本编辑器>显示>显示文件编码” 全局设置 选择“工具>首选项>文本编辑器>行为>文件编码” 将文件编码设置为utf-8&#xff0c;UTF-8 BOM 选择存在则保留&#xff0c;最后选择apply。 打开项目设置 选择“项目&…

解析HTTP/2如何提升网络速度

我们知道HTTP/1.1 为网络效率做了大量的优化&#xff0c;最核心的有如下三种方式&#xff1a; 增加了持久连接&#xff1b;浏览器为每个域名最多同时维护 6 个 TCP 持久连接&#xff1b;使用 CDN 的实现域名分片机制。 虽然 HTTP/1.1 采取了很多优化资源加载速度的策略&#x…

[学习笔记]SQL server完全备份指南

方式一&#xff0c;使用SQL Server Management Studio 准备工作 连接目标数据库服务器 在目标数据库上右键->属性&#xff0c;将数据库的恢复模式设置为“简单”&#xff0c;兼容级别设置为“SQL Server 2016(130)” [可选]将表中将无用的业务数据删除&#xff0c;以减…

Java EE|TCP/IP协议栈之传输层UDP协议详解

文章目录一、对UDP协议的感性认识简介主要特点二、UDP的报文结构协议端格式概览报文结构详解源端口目的端口16位UDP报文长度16位校验和参考一、对UDP协议的感性认识 简介 UDP&#xff0c;是User Datagram Protocol的简称&#xff0c;中文名是用户数据报协议&#xff0c;是OSI…

Leetcode力扣秋招刷题路-0081

从0开始的秋招刷题路&#xff0c;记录下所刷每道题的题解&#xff0c;帮助自己回顾总结 81. 搜索旋转排序数组 II 已知存在一个按非降序排列的整数数组 nums &#xff0c;数组中的值不必互不相同。 在传递给函数之前&#xff0c;nums 在预先未知的某个下标 k&#xff08;0 &…

公安局靶场建设规划设计

随着我国国家安全形势的变化&#xff0c;公安工作也面临着越来越严峻的挑战。为了提高公安干警的专业技能和反恐能力&#xff0c;建设一座现代化的靶场已成为公安局的迫切需求。本文将介绍公安局靶场建设的重要性&#xff0c;靶场的规划与设计以及建设过程中需要注意的事项。 一…

Pyspark基础入门4_RDD转换算子

Pyspark 注&#xff1a;大家觉得博客好的话&#xff0c;别忘了点赞收藏呀&#xff0c;本人每周都会更新关于人工智能和大数据相关的内容&#xff0c;内容多为原创&#xff0c;Python Java Scala SQL 代码&#xff0c;CV NLP 推荐系统等&#xff0c;Spark Flink Kafka Hbase Hi…

Flex写法系列-Flex布局之基本语法

以前的传统布局&#xff0c;依赖盒装模型。即 display position float 属性。但是对于比较特殊的布局就不太容易实现&#xff0c;例如&#xff1a;垂直居中。下面主要介绍flex的基本语法&#xff0c;后续还有二期介绍Flex的写法。一、什么是Flex布局&#xff1f;Flex布局个人…

Vuex的创建和简单使用

Vuex 1.简介 1.1简介 1.框框里面才是Vuex state&#xff1a;状态数据action&#xff1a;处理异步mutations&#xff1a;处理同步&#xff0c;视图可以同步进行渲染1.2项目创建 1.vue create 名称 2.运行后 3.下载vuex。采用的是基于vue2的版本。 npm install vuex3 --save 4.vu…

Frequency Domain Model Augmentation for Adversarial Attack

原文&#xff1a;[2207.05382] Frequency Domain Model Augmentation for Adversarial Attack (arxiv.org)代码&#xff1a;https://github.com/yuyang-long/SSA.黑盒攻击替代模型与受攻击模型之间的差距通常较大&#xff0c;表现为攻击性能脆弱。基于同时攻击不同模型可以提高…

C++8:模拟实现list

目录 最基础的链表结构以及迭代器实现 链表节点结构 构造函数 push_back list的迭代器 增删查改功能实现 insert erase pop_front pop_back push_front clear 默认成员函数 析构函数 拷贝构造函数 赋值操作符重载 list的完善 const迭代器 赋值操作符重…

使用BP神经网络诊断恶性乳腺癌(Matlab代码实现)

目录 &#x1f4a5;1 概述 &#x1f4da;2 运行结果 &#x1f389;3 参考文献 &#x1f468;‍&#x1f4bb;4 Matlab代码 &#x1f4a5;1 概述 1.1.算法简介 BP&#xff08;Back Propagation&#xff09;网络是1986年由Rumelhart和McCelland为首的科学家小组提出&#xf…

c语言编程规范第三部分

3、头文件应向稳定的方向包含 头文件的包含关系是一种依赖&#xff0c;一般来说&#xff0c;应当让不稳定的模块依赖稳定的模块&#xff0c;从而当不稳定的模块发生变化时&#xff0c;不会影响&#xff08;编译&#xff09;稳定的模块。就我们的产品来说&#xff0c;依赖的方向…

数据复制 软件 SnapMirror:统一复制,更快恢复

数据复制 软件 SnapMirror&#xff1a;统一复制&#xff0c;更快恢复 预测未知领域是一项棘手的工作。让 SnapMirror 软件来处理则轻松得多。 通过数据的高可用性和快速数据复制&#xff0c;可即时访问业务关键型数据。放松一下&#xff0c;它会让你满意的。 为什么用 SnapMi…

3D目标检测(一)—— 基于Point-Based方法的PointNet系列

3D目标检测&#xff08;一&#xff09;—— PointNet&#xff0c;PointNet&#xff0c;PointNeXt&#xff0c; PointMLP 目录 3D目标检测&#xff08;一&#xff09;—— PointNet&#xff0c;PointNet&#xff0c;PointNeXt&#xff0c; PointMLP 前言 零、网络使用算法 …

AQS与Synchronized异曲同工的加锁流程

在并发多线程的情况下&#xff0c;为了保证数据安全性&#xff0c;一般我们会对数据进行加锁&#xff0c;通常使用Synchronized或者ReentrantLock同步锁。Synchronized是基于JVM实现&#xff0c;而ReentrantLock是基于Java代码层面实现的&#xff0c;底层是继承的AQS。 AQS全称…

c++函数对象(仿函数)、谓词、内建函数对象

1、函数对象 1.1 概念 重载函数调用操作符的类&#xff0c;这个类的对象就是函数对象&#xff0c;在使用这个函数对象对应使用重载的&#xff08;&#xff09;符号时&#xff0c;行为类似于函数调用&#xff0c;因此这个函数也叫仿函数。 注意&#xff1a;函数对象&#xff0…

多个任务并行的时候,你是否总是会手忙脚乱?

很多重要事情之所以变得迫在眉睫&#xff0c;需要立刻处理、应付&#xff0c;是因为被延误或没有进行足够的预防和准备&#xff0c;筹划。 面对多个任务并行的时候&#xff0c;你是否总是会手忙脚乱&#xff1f; 在项目工作中&#xff0c;管理者每天要面对各种工作&#xff…

移动WEB开发二、流式布局

零、文章目录 文章地址 个人博客-CSDN地址&#xff1a;https://blog.csdn.net/liyou123456789个人博客-GiteePages&#xff1a;https://bluecusliyou.gitee.io/techlearn 代码仓库地址 Gitee&#xff1a;https://gitee.com/bluecusliyou/TechLearnGithub&#xff1a;https:…