【顺序栈的实现1】--------含栈顶,栈底指针;栈顶指针指向栈顶元素的下一个位置

news2024/12/23 11:06:14

1. 栈的抽象数据类型定义:

在这里插入图片描述

2.顺序栈的存储方式

同一般线性表的顺序存储结构完全相同:
利用一组地址连续的存储单元依次存放自栈底到栈顶的数据元素栈底一般在低地址端。

  • 附设top指针指示栈顶元素在顺序栈中的位置
  • 另设base指针指示栈底元素在顺序栈中的位置
  • 另外,用stacksize表示栈可使用的最大容量

但是,为了方便操作,通常top指向真正的栈顶元素 之上的 下标地址,如下图
在这里插入图片描述

3.顺序栈的相关基础操作汇总

  • 初始化操作:操作结果:构造一个空栈 S。
InitStack(SqStack* s)
  • 判定S是否为空栈:
    初始条件:栈S 已存在。
    操作结果:若栈S为空栈,则返回TRUE,否则 FALSE.
StackEmpty(SqStack s)
  • 求栈的长度
    初始条件:栈S 已存在。
    操作结果:返回S的元素个数,即栈的长度
StackLength(SqStack s)
  • 栈置空操作:
    初始条件:栈S 已存在。
    操作结果:将S清为空栈。
ClearStack(SqStack * s)
  • 销毁栈操作:
    初始条件:栈S 已存在。
    操作结果:栈S 被销毁。
DestroyStack(SqStack *s)
  • 入栈操作(重点)
    初始条件:栈S已存在且未满
    操作结果:插入元素e为新的栈顶元素。
Push(SqStack* s, SElemType e)
  • 出栈操作(重点)
    初始条件:栈S 已存在且非空:
    操作结果:删除S的栈顶元素a.,并用e返回其值。
Pop(SqStack* s, SElemType* e)
  • 取栈顶元素
    初始条件:栈S 已存在且非空。
    操作结果:用e返回S的栈顶元素。
GetTop(SqStack s, SElemType* e)
  • 从栈顶开始输出整栈
    初始条件:栈S 已存在且非空。
    操作结果:从栈顶输出栈中所有元素。
printStack(SqStack s)

4.整栈操作模拟与异常分析

4.1操作模拟:

由于本篇中顺序栈含栈顶,栈底指针并且栈顶指针指向栈顶元素的下一个位置
在这里插入图片描述
所以空栈与栈满的判断条件也有所不同:
在这里插入图片描述

4.2异常处理:

使用数组作为顺序栈存储方式的特点:
在这里插入图片描述
而这里我们要注意:
上溢是一种错误,使问题的处理无法进行;
而下溢一般认为是一种结束条件,即问题处理结束。

5.顺序栈的整表创建(含栈底,栈顶指针)

5.1顺序栈的结构定义:
typedef struct Sqstack
{
	SElemType* base;//栈底指针
	SElemType* top;//栈顶指针

	int stacksize;//栈可用的最大容量
}SqStack;
  • 在结构定义中,一个顺序栈里包含了栈底指针栈顶指针,以及栈可用的最大容量这三个部分
  • 而别名SqStack用来定义顺序栈
    SqStack* 用来表示指向栈的指针
5.2顺序栈的初始化

注意:传入参数时,需传入栈的指针,即&s,这样才能修改栈中的数据

bool InitStack(SqStack* s)
5.2.1算法步骤:

(1)为顺序栈初始化空间,同时让栈底指针(base)指向被初始化的空间
(2)初始化栈顶指针 指向栈底位置
(3)初始化该顺序栈的最大容量

在这里插入图片描述

//2.顺序栈的初始化
//注意:传入参数时,需传入栈的指针,即&s,这样才能修改栈中的数据
bool InitStack(SqStack* s)
{
	//[1]为顺序栈初始化空间,同时让栈底指针指向被初始化的空间
	s->base = (SElemType *)malloc(sizeof(SElemType) * MAXSIZE);

	if (s->base == NULL)
	{
		printf("内存分配失败!\n");
		exit(-1);
	}

	//[2]初始化栈顶指针 指向栈底位置
	s->top = s->base;

	//[3]初始化该顺序栈的最大容量
	s->stacksize = MAXSIZE;
	return true;
}
5.3判断顺序栈是否为空

注意:传入参数时,不需要传入栈的指针,即&s,因为判空操作只需要访问栈顶指针与栈底指针,并不做修改

bool StackEmpty(SqStack s)
5.3.1算法步骤:

(1)若栈顶指针与栈底指针相同,说明栈空;否则栈非空

在这里插入图片描述

//3.判断顺序栈是否为空
//注意:传入参数时,不需要传入栈的指针,即&s,因为判空操作只需要访问栈顶指针与栈底指针,并不做修改
bool StackEmpty(SqStack s)
{

	//[1]若栈顶指针与栈底指针相同,说明栈空
	if (s.top == s.base)
	{
		return true;
	}
	else
	{
		return false;
	}
}
5.4求顺序栈的长度

注意:传入参数时,不需要传入栈的指针,即&s,因为求长度只需要计算栈顶指针与栈底指针之差,并不做修改

int StackLength(SqStack s)
5.4.1算法步骤:

(1)栈顶指针 与 栈底指针的 差值即为顺序栈的长度

这里直接使用指针的差值,不需要"/sizeof(SqElemType)";因为两个指针的基类型为同一类型,其相减结果即为顺序栈的长度
在这里插入图片描述

//4.求顺序栈的长度
//注意:传入参数时,不需要传入栈的指针,即&s,因为求长度只需要计算栈顶指针与栈底指针之差,并不做修改
int StackLength(SqStack s)
{
	//栈顶指针 与 栈底指针的 差值即为顺序栈的长度
	return s.top - s.base;
}
5.5清空顺序栈

注意:传入参数时,需要传入栈的指针,即&s,因为清空栈需要修改栈顶指针,即s.top

bool ClearStack(SqStack * s)
5.5.1算法步骤:

(1)判断栈内存是否分配(通过判断栈底指针是否为空来实现)
(2)修改栈顶指针指向栈底位置即为清空(由于进栈时值会覆盖,故不需要删除元素值)

在这里插入图片描述
在这里插入图片描述

//5.清空顺序栈
//注意:传入参数时,需要传入栈的指针,即&s,因为清空栈需要修改栈顶指针,即s.top
bool ClearStack(SqStack * s)
{
	//[1]判断栈内存是否分配
	if (s->base == NULL)
	{
		printf("栈不存在!\n");
		return false;
	}

	//[2]修改 栈顶指针 指向 栈底位置,即为清空
	//(由于进栈时值会覆盖,故不需要删除元素值)
	s->top = s->base;
	return true;
}
5.6销毁顺序栈

注意:传入参数时,需要传入栈的指针,即&s,因为销毁栈需要修改清空内存,并置空栈中指针以及栈大小

bool DestroyStack(SqStack *s)
5.6.1算法步骤:

(1)若当前顺序栈存在,则先释放内存,再置空栈大小以及栈指针
<1>通过栈底指针释放内存
<2>置空栈大小以及栈指针(防止悬挂指针问题)

最终栈里除了stacksize,base和top被置空以外,其余部分均被销毁

//6.销毁顺序栈
//注意:传入参数时,需要传入栈的指针,即&s,因为销毁栈需要修改清空内存,并置空栈中指针以及栈大小
bool DestroyStack(SqStack *s)
{
	//[1]若当前顺序栈存在,则先释放内存,再置空栈大小以及栈指针
	if (s->base != NULL)
	{
		//<1>通过栈底指针释放内存
		free(s->base);
		
		//<2>置空栈大小以及栈指针
		s->stacksize = 0;

		s->base = NULL;
		s->top = NULL;
	}
	return true;
}
5.7顺序栈的入栈(核心1)

注意:传入参数时,需要传入栈的指针,即&s,因为入栈操作需要 更改栈顶指针以及 添加栈顶元素

bool Push(SqStack* s, SElemType e)
5.7.1算法步骤:

(1)判断栈是否已满(即 栈顶指针 与 栈底指针 之差 是否等于 栈的最大容量)
(2)入栈操作:
<1>先将元素e赋值给栈顶指针当前指向的位置
<2>然后栈顶指针自增1,指向当前 栈顶元素的 下一个位置

入栈操作可以浓缩为一步:
*s->top++ = e;

在这里插入图片描述

//7.核心1:顺序栈的入栈
//注意:传入参数时,需要传入栈的指针,即&s,因为入栈操作需要 更改栈顶指针以及 添加栈顶元素
bool Push(SqStack* s, SElemType e)
{
	//[1]判断栈是否已满(即 栈顶指针 与 栈底指针 之差 是否等于 栈的最大容量)
	if (s->top - s->base == s->stacksize)
	{
		printf("栈满!\n");
		return false;
	}

	//[2]入栈操作:
	//<1>先将元素e赋值给栈顶指针当前指向的位置
	*(s->top) = e;
	
	//<2>然后栈顶指针自增1,指向当前 栈顶元素的 下一个位置
	(s->top)++;
	//等价于 *s->top++ = e;先赋值,再向下移动

	return true;

}
5.8顺序栈的出栈(核心2)

注意:传入参数时,需要传入栈的指针,即&s,因为出栈操作需要 更改栈顶指针以及 带出栈顶元素

bool Pop(SqStack* s, SElemType* e)
5.8.1算法步骤:

(1)判断是否栈空(即栈顶指针 是否与 栈底指针指向相同)
(2)出栈操作:
<1>先将栈顶指针自减1,让其指向当前栈顶元素
<2>再将当前栈顶指针指向的栈顶元素 赋值给e
出栈操作可以浓缩为一步:

*e= *(–s->top);

在这里插入图片描述

//8.核心2:顺序栈的出栈
//注意:传入参数时,需要传入栈的指针,即&s,因为出栈操作需要 更改栈顶指针以及 带出栈顶元素
bool Pop(SqStack* s, SElemType* e)
{
	//[1]判断是否栈空(即栈顶指针 是否与 栈底指针指向相同)
	if (s->base == s->top)
	{
		printf("栈空!\n");
		return false;
	}

	//[2]出栈操作:
	//<1>先将栈顶指针自减1,让其指向当前栈顶元素
	--s->top;

	//<2>再将当前栈顶指针指向的栈顶元素 赋值给e
	*e = *(s->top);
	//等价于:*e=*(--s->top);先向底部移动栈顶指针,再取出栈顶元素
	return true;
}
5.9取栈顶元素

注意:传入参数时,不需要传入栈的指针,即&s,因为只取元素,不修改栈的数据

bool GetTop(SqStack s, SElemType* e)
5.9.1算法步骤:

(1)判断栈是否为空
(2)获取栈顶元素(注意是s.top - 1处的元素)

//9.取栈顶元素
//注意:传入参数时,不需要传入栈的指针,即&s,因为只取元素,不修改栈的数据
bool GetTop(SqStack s, SElemType* e)
{
	//[1]判断栈是否为空
	if (s.base == s.top)
	{
		printf("栈空!\n");
		return false;
	}

	//[2]获取栈顶元素:
	*e = *(s.top - 1);
	return true;
}
5.10输出顺序栈中的所有元素(从顺序栈顶开始输出)
bool printStack(SqStack s)
5.10.1算法步骤:

(1)判断该顺序栈是否为空
(2)定义临时指针指向当前栈顶元素(s.top - 1处的元素)
(3)p从栈顶开始,向栈底移动并依次输出栈中的元素

//10.输出顺序栈中的所有元素(从顺序栈顶开始输出)
bool printStack(SqStack s)
{
	//[1]判断该顺序栈是否为空
	if (s.base == s.top)
	{
		printf("顺序栈为空!\n");
		return false;
	}

	//[2]定义临时指针指向当前栈顶元素
	SElemType* p = s.top - 1;

	//[3]p从栈顶开始,向栈底移动并依次输出栈中的元素
	while (p>=s.base)
	{
		printf("%d-->", *(p));
		p--;
	}

	printf("end\n");
	return true;
}

21.所有操作如下:

//顺序栈的基本操作与实现(1.为了操作方便,栈顶指针指向栈顶元素的下一位置)
                     //(2.直接使用指针来定义栈顶,栈底指针)
#include<stdio.h>
#include<stdlib.h>


#define bool int
#define true 1
#define false 0

typedef int SElemType;//栈中数据元素的类型定义     


#define MAXSIZE 100//顺序栈的最大容量


//1.顺序栈的结构(这里直接使用指针来  定义栈顶指针  与  栈底指针)
//实际上也可以使用int类型的角标来模拟栈顶,栈底指针
typedef struct Sqstack
{
	SElemType* base;//栈底指针
	SElemType* top;//栈顶指针

	int stacksize;//栈可用的最大容量
}SqStack;


//2.顺序栈的初始化
//注意:传入参数时,需传入栈的指针,即&s,这样才能修改栈中的数据
bool InitStack(SqStack* s)
{
	//[1]为顺序栈初始化空间,同时让栈底指针指向被初始化的空间
	s->base = (SElemType *)malloc(sizeof(SElemType) * MAXSIZE);

	if (s->base == NULL)
	{
		printf("内存分配失败!\n");
		exit(-1);
	}

	//[2]初始化栈顶指针 指向栈底位置
	s->top = s->base;

	//[3]初始化该顺序栈的最大容量
	s->stacksize = MAXSIZE;
	return true;
}

//3.判断顺序栈是否为空
//注意:传入参数时,不需要传入栈的指针,即&s,因为判空操作只需要访问栈顶指针与栈底指针,并不做修改
bool StackEmpty(SqStack s)
{

	//[1]若栈顶指针与栈底指针相同,说明栈空
	if (s.top == s.base)
	{
		return true;
	}
	else
	{
		return false;
	}
}


//4.求顺序栈的长度
//注意:传入参数时,不需要传入栈的指针,即&s,因为求长度只需要计算栈顶指针与栈底指针之差,并不做修改
int StackLength(SqStack s)
{
	//栈顶指针 与 栈底指针的 差值即为顺序栈的长度
	return s.top - s.base;
}


//5.清空顺序栈
//注意:传入参数时,需要传入栈的指针,即&s,因为清空栈需要修改栈顶指针,即s.top
bool ClearStack(SqStack * s)
{
	//[1]判断栈内存是否分配
	if (s->base == NULL)
	{
		printf("栈不存在!\n");
		return false;
	}

	//[2]修改 栈顶指针 指向 栈底位置,即为清空
	//(由于进栈时值会覆盖,故不需要删除元素值)
	s->top = s->base;
	return true;
}

//6.销毁顺序栈
//注意:传入参数时,需要传入栈的指针,即&s,因为销毁栈需要修改清空内存,并置空栈中指针以及栈大小
bool DestroyStack(SqStack *s)
{
	//[1]若当前顺序栈不为空,则先释放内存,再置空栈大小以及栈指针
	if (s->base != NULL)
	{
		//<1>通过栈底指针释放内存
		free(s->base);
		
		//<2>置空栈大小以及栈指针
		s->stacksize = 0;

		s->base = NULL;
		s->top = NULL;
	}
	return true;
}


//7.核心1:顺序栈的入栈
//注意:传入参数时,需要传入栈的指针,即&s,因为入栈操作需要 更改栈顶指针以及 添加栈顶元素
bool Push(SqStack* s, SElemType e)
{
	//[1]判断栈是否已满(即 栈顶指针 与 栈底指针 之差 是否等于 栈的最大容量)
	if (s->top - s->base == s->stacksize)
	{
		printf("栈满!\n");
		return false;
	}

	//[2]入栈操作:
	//<1>先将元素e赋值给栈顶指针当前指向的位置
	*(s->top) = e;
	
	//<2>然后栈顶指针自增1,指向当前 栈顶元素的 下一个位置
	(s->top)++;
	//等价于 *s->top++ = e;先赋值,再向下移动

	return true;

}

//8.核心2:顺序栈的出栈
//注意:传入参数时,需要传入栈的指针,即&s,因为出栈操作需要 更改栈顶指针以及 带出栈顶元素
bool Pop(SqStack* s, SElemType* e)
{
	//[1]判断是否栈空(即栈顶指针 是否与 栈底指针指向相同)
	if (s->base == s->top)
	{
		printf("栈空!\n");
		return false;
	}

	//[2]出栈操作:
	//<1>先将栈顶指针自减1,让其指向当前栈顶元素
	--s->top;

	
	//<2>再将当前栈顶指针指向的栈顶元素 赋值给e
	*e = *(s->top);
	//等价于:*e=*(--s->top);先向底部移动栈顶指针,再取出栈顶元素
	return true;
}


//9.取栈顶元素
//注意:传入参数时,不需要传入栈的指针,即&s,因为只取元素,不修改栈的数据
bool GetTop(SqStack s, SElemType* e)
{
	//[1]判断栈是否为空
	if (s.base == s.top)
	{
		printf("栈空!\n");
		return false;
	}

	//[2]获取栈顶元素:
	*e = *(s.top - 1);
	return true;
}




//10.输出顺序栈中的所有元素(从顺序栈顶开始输出)
bool printStack(SqStack s)
{
	//[1]判断该顺序栈是否为空
	if (s.base == s.top)
	{
		printf("顺序栈为空!\n");
		return false;
	}

	//定义临时指针指向当前栈顶元素
	SElemType* p = s.top - 1;

	//p从栈顶开始,向栈底移动并依次输出栈中的元素
	while (p>=s.base)
	{
		printf("%d-->", *(p));
		p--;
	}

	printf("end\n");
	return true;
}



int main()
{
	SqStack s1;
	InitStack(&s1);  // 初始化栈

	// 入栈
	Push(&s1, 10);  
	Push(&s1, 20);
	Push(&s1, 30);
	Push(&s1, 31);
	Push(&s1, 32);

	printf("当前栈的长度: %d\n", StackLength(s1));
	printf("\n");

	// 获取栈顶元素
	SElemType ee;
	GetTop(s1, &ee);
	printf("当前栈顶元素为:%d\n", ee);

	printf("\n");
	printf("从当前栈顶元素向下输出:\n");
	printStack(s1);

	// 出栈
	printf("\n");
	SElemType e[10];
	for (int i = 0; i < 3; i++)
	{
		Pop(&s1, &e[i]);
		printf("出栈元素: %d\n", e[i]);
	}

	printf("\n");
	printf("从当前栈顶元素向下输出:\n");
	printStack(s1);

	// 清空栈
	ClearStack(&s1); 
	
	printf("栈是否为空: \n");
	if (StackEmpty(s1))
	{
		printf("栈为空!\n");
	}

	// 销毁栈
	if (DestroyStack(&s1))
	{
		printf("销毁成功!\n");
	}

	return 0;
}

在这里插入图片描述

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

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

相关文章

<数据集>斯坦福狗狗识别数据集<目标检测>

数据集格式&#xff1a;VOCYOLO格式 图片数量&#xff1a;20580张 标注数量(xml文件个数)&#xff1a;20580 标注数量(txt文件个数)&#xff1a;20580 标注类别数&#xff1a;120 标注类别名称&#xff1a;[Chihuahua, Japanese_spaniel, Maltese_dog, Pekinese, Shih-Tzu…

快速排序(Java实现)

目录 快速排序的思想 代码实现 思路 代码 快速排序的特点 快速排序的思想 快速排序和冒泡排序一样&#xff0c;是一种交换排序。快速排序的核心思想也是分治&#xff0c;分而治之。给定一个数组&#xff0c;先选定一个元素作为枢轴&#xff0c;然后将大于枢轴的放在右边&a…

Javaweb学习之Vue项目的创建(二)

学习资料 Vue.js - 渐进式 JavaScript 框架 | Vue.js (vuejs.org) 准备工作都做完了&#xff0c;接下来开始Vue的正式学习。 第一步&#xff0c;打开VS Code 在VS Code里&#xff0c;我们也需要使用到终端&#xff0c;如果不是以管理员身份打开&#xff0c;在新建Vue项目的时候…

围棋棋盘的图像(识别)240801

识别: import tensorflow as tf import numpy as np from tensorflow.keras import layers, models from tensorflow.keras.utils import to_categorical from tensorflow.keras.preprocessing.image import load_img, img_to_array# 加载并预处理图像 def load_and_preproces…

Linux升级lib64中的libc.so.6导致所有命令失效

ls: relocation error: libpthread.so.0: symbol __libc_dl_error_tsd, version GLIBC_PRIVATE not defined in file libc.so.6 with link time reference 升级Glibc后出现所有shell命令都不可用 # systemctl status systemctl: relocation error: /lib64/libpthread.so.0: sy…

为视觉语言多模态模型进行偏好优化

训练模型使得它能够理解并预测人类偏好是一项比较复杂的任务。诸如 SFT (Supervised finetuning) 的传统的方法一般都需要耗费较大成本&#xff0c;因为这些算法需要对数据打上特定的标签。而偏好优化 (Preference Optimization) 作为一种替代选项&#xff0c;通常可以简化这一…

【10-21】设计原则

目录 一.开闭原则 二.里氏代换原则 三.依赖倒转原则 四.接口隔离原则 五.迪米特法则 六.合成复用原则 前言&#xff1a; 在软件开发中&#xff0c;为了提高软件系统的可维护性和可复用性&#xff0c;增加软件的可拓展性和灵活性&#xff0c;程序员要尽量根据6条原则来开发…

关于WebSocket必知必会的知识点

什么是WebSocket WebSocket是一种网络传输协议&#xff0c;可以在单个TCP连接上进行全双工通信&#xff0c;位于OSI模型的应用层。 WebSocket使得客户端和服务器之间的数据交换变得更加简单&#xff0c;服务器可以主动向客户端发送消息。在WebSocket API中&#xff0c;浏览器和…

20240820让飞凌的OK3588-C的核心板在Linux R4下挂载1TB的NTFS格式的TF卡

fdisk -l df -h df -t df -T mount 20240820让飞凌的OK3588-C的核心板在Linux R4下挂载1TB的NTFS格式的TF卡 2024/8/20 18:03 【默认挂载到/run/media/mmcblk1&#xff0c;不用任何操作&#xff01;】 插入1TB的TF卡之后的dmesg信息&#xff1a; [ 876.551728] fdee0000.hdmi…

pandans读写分析csv文件

1.什么是pandans Pandas 是一个强大的 Python 库&#xff0c;主要用于数据处理和数据分析。它为 Python 提供了高效的数据结构和数据分析工具&#xff0c;使得数据处理变得更加简单和直观。 2.什么事csv文件 CSV 文件&#xff08;Comma-Separated Values&#xff0c;逗号分隔值…

点亮宇宙的温暖之光 —— COSMOSPANDA星际熊猫“寞”降临!

在这个科技日新月异的时代&#xff0c;我们往往在追求进步的同时&#xff0c;忽略了心中那份最真挚的情感与温暖。但今天&#xff0c;让我们共同迎接一位来自宇宙深处的温暖使者——COSMOSPANDA星际熊猫“寞”&#xff0c;它将用独特的方式&#xff0c;连接过去与未来&#xff…

3:2比例的程序员专业显示器,效率提升显著,摸鱼时间又多了

对于我们程序员来说&#xff0c;显示器的重要性不言而喻&#xff0c;作为我们与代码交流的直接工具&#xff0c;他影响着我们的工作效率、舒适度和整体编程体验。我在家用的是自己笔记本的屏幕&#xff0c;简单写写代码还行&#xff0c;涉及到多任务协同或者大代码量开发就有点…

Linux 下安装miniconda(少走弯路)

Miniconda 和 Conda 都是用于管理 Python&#xff08;及其他语言&#xff09;环境和包的工具。 conda对于我来说是太臃肿了&#xff0c;很多的包我不会使用&#xff0c;所以选择安装miniconda是一个较好的选择。 下面是linux安装miniconda的实际操作。 在以下的网站&#xf…

复现 LET-NET

摘要 稀疏光流法是计算机视觉中的一项基本任务。然而&#xff0c;它依赖于恒定的假设限制了其在高动态范围&#xff08;HDR&#xff09;场景中的适用性。在本研究中&#xff0c;我们提出了一种新的方法&#xff0c;旨在通过学习一个对光照变化具有鲁棒性的特征映射来超越图像的…

LabVIEW轨距实时动态检测系统

轨距实时动态检测系统解决铁路轨距不平顺现象&#xff0c;提高铁路运行安全性。系统利用高精度的激光位移传感器与数据同步采集技术&#xff0c;结合LabVIEW软件进行数据处理&#xff0c;有效提高了轨距检测的准确性与效率。 项目背景 随着铁路运输业的快速发展&#xff0c;轨…

速度+耐力,希迪智驾引领中国商用车自动驾驶发展

作者 | 魏启扬 来源 | 洞见新研社 资本市场对自动驾驶的投资热情依然不减。 不久前&#xff0c;科技巨头Alphabet重申了对自动驾驶未来的承诺&#xff0c;并表示将向其自动驾驶子公司Waymo投资50亿美元&#xff0c;分多年进行。 更早一点的5月份&#xff0c;孙正义旗下的…

如何使用 JavaScript 动态创建下拉框?

在现代 Web 开发中&#xff0c;动态生成页面元素是一个常见的需求&#xff0c;比如在用户选择某个选项后&#xff0c;根据选择的内容动态生成新的下拉框。今天&#xff0c;我们来聊一聊如何使用 JavaScript 动态创建一个带选项的下拉框&#xff0c;并用一个具体的场景带大家进入…

第十九讲 python中的异常本质-异常定位-异常解决思路

目录 1.异常是什么&#xff1f; 2.异常机制的本质 2.1 本质 2.2 异常对象 2.3 抛出异常 2.4 捕捉异常 2.5 最终处理 3.异常的解决思路 3.1 异常定位 3.2 异常解决 1.异常是什么&#xff1f; 异常是指程序在运行时发生的错误或不正常情况。 工作中&#xff0c;程序遇到的情况不…

数据结构中的双向链表

1.链表的分类 链表的结构非常多样&#xff0c;以下情况组合起来就是8种&#xff08;2x2x2&#xff09;链表结构&#xff1a; 在带头链表中&#xff0c;除了头结点&#xff0c;其他结点均存储有效的数据。 头结点是占位子的&#xff0c;也叫做“哨兵位”。head结点就是头结点。…

【实战场景】如何优雅实现分页

【实战场景】如何优雅实现分页 开篇词&#xff1a;干货篇&#xff1a;1.添加PageHelper依赖2.添加PageHelper配置3.使用 PageHelper4.自定义Pageable注解 总结&#xff1a;1.执行查询2.处理分页结果3.注意事项 我是杰叔叔&#xff0c;一名沪漂的码农&#xff0c;下期再会&#…