当前位置: 首页 > news >正文

【数据结构】第七节:堆

 个人主页 深情秋刀鱼@-CSDN博客 

 数据结构专栏:数据结构与算法

源码获取:数据结构: 上传我写的关于数据结构的代码 (gitee.com)

目录

一、堆

1.堆的概念

2.堆的定义

二、堆的实现

1.初始化和销毁

2.插入

向上调整算法

3.删除

向下调整算法

4.取堆顶元素

5.判空

三、Top_k问题

1.问题描述

2.面试中的Top_k问题

四、堆排序

1.建堆

 2.堆排序

五、堆的时间复杂度

1.建堆

a.树中高度与节点的关系

b.向下调整建堆算法

c.向上调整建堆算法

 2.堆排序


一、堆

1.堆的概念

         堆是一棵完全二叉树,且其中的节点总是不大于(或不小于某个值)。如果堆中的节点总是不大于某个值(根节点最大),称为大根堆;如果堆中的节点总是不小于某个值(根节点最小)将根节点最小的堆称为小根堆。

        大根堆和小根堆描述的是双亲节点和子节点之间的关系,而子节点之间没有直接的联系。

2.堆的定义

typedef int HPDataType;//堆
typedef struct Heap
{HPDataType* a;int size;int capacity;
}Heap;

        二叉树一般可以使用两种结构存储,一种顺序结构(数组),一种链式结构(链表)。由于堆是一棵完全二叉树,用数组结构存储较为简洁。

        数组中双亲节点和子节点之间的关系:

  • 当双亲结点的下标为i时,左子节点的下标=2 * i + 1,右子节点的下标=2 * i + 2
  • 当子节点的下标为i时,双亲节点的下标=(i - 1)/ 2

二、堆的实现

1.初始化和销毁

//初始化
void HPInit(Heap* php)
{assert(php);php->a = NULL;php->size = php->capacity = 0;
}//销毁
void HPDestroy(Heap* php)
{assert(php);free(php->a);php->a = NULL;php->size = php->capacity = 0;
}

2.插入

        堆在内存中是以数组的形式存储的,在逻辑上需要将数组看成一棵完全二叉树。向堆中插入数据时要保证堆的结构不被破坏,并将其调整为小根堆或大根堆时需要用到向上调整算法

向上调整算法

        使用前提:左右子树必须是一个堆,才能调整。

        算法实现:以小根堆为例,在数组尾部(下标为size-1)的位置插入数据(记下标为child),被插入数据child通过下标之间的关系找到child所在的这棵子树的根(记下标为parent)并与根节点比较,如果a[child]<a[parent]说明此时双亲节点大于子结点的,不符合小根堆的性质,此时需要交换child与parent的位置并更新child和parent的值,一直到堆顶(下标为0)则调整结束。

//交换
void Swap(HPDataType* a, HPDataType* b)
{HPDataType tmp = *b;*b = *a;*a = tmp;
}//向上调整算法(小根堆)
void AdjustUP(HPDataType* a, int child)
{int parent = (child - 1) / 2;while (child > 0){if (a[parent] > a[child]){Swap(&a[parent], &a[child]);child = parent;parent = (child - 1) / 2;//更新下标值}elsebreak;}
}
  •  图解(小根堆):

  • 代码实现:
//插入
void HPPush(Heap* php, HPDataType x)
{assert(php);if (php->size == php->capacity){int newcapacity = php->capacity == 0 ? 4 : php->capacity * 2;HPDataType* tmp = (HPDataType*)realloc(php->a, newcapacity * sizeof(HPDataType));if (tmp == NULL){perror("realloc fail!");return;}php->a = tmp;php->capacity = newcapacity;}php->a[php->size++] = x;AdjustUP(php->a, php->size - 1);
}

3.删除

        删除规定只删除堆顶元素(删除堆尾元素size--即可),删除堆顶元素的同时需要保持结构不变,需要用到向下调整算法。

向下调整算法

        使用前提:左右子树必须是一个堆,才能调整。

        算法实现:以小根堆为例,将首(B)尾(A)元素交换,在尾部删除堆顶元素B,在堆顶的尾元素A通过向下调整算法调整到合适的位置再形成堆。新的堆顶元素A下标为0(记为parent),以parent为根的两个子节点分别为左child节点(下标2*parent+1)、右child节点(下标2*parent+2),为满足小根堆的性质,我们需要在这两个节点中找到较小的一个与元素A交换成为新的根,元素A成为子节点后再向下寻找以元素A为根的两个子节点,一直到堆底调整结束。

//向下调整算法
void AdjustDown(HPDataType* a, int n, int parent)
{//假设法int child = 2 * parent + 1;while (child < n){//两个子节点中较小的那个(注意边界的处理)if (child + 1 < n && a[child] > a[child + 1])child++;if (a[parent] > a[child]){Swap(&a[parent], &a[child]);parent = child;child = 2 * parent + 1;}elsebreak;}
}

        在判断两个子节点的大小时不妨先假设左子节点大,进入循环后再判断左右子节点的大小。

  • 图解(小根堆): 

  •  代码实现:
//删除(删除堆顶的数据)
void HPPop(Heap* php)
{assert(php && php->size > 0);Swap(&php->a[0], &php->a[php->size - 1]);php->size--;AdjustDown(php->a, php->size, 0);
}

4.取堆顶元素

//取堆顶
HPDataType HPTop(Heap* php)
{assert(php && php->size > 0);return php->a[0];
}

5.判空

//判空
bool HPEmpty(Heap* php)
{assert(php);return php->size == 0;
}

三、Top_k问题

1.问题描述

        TOP-K问题:即求数据结合中前K个最大的元素或者最小的元素,一般情况下数据量都比较大。 比如:专业前10名、世界500强、富豪榜、游戏中前100的活跃玩家等。
对于Top-K问题,能想到的最简单直接的方式就是排序,但是:如果数据量非常大,排序就不太可取了(可能数据都不能一下子全部加载到内存中)。最佳的方式就是用堆来解决,基本思路如下:
1. 用数据集合中前K个元素来建堆
  • 前k个最大的元素,则建小堆
  • 前k个最小的元素,则建大堆
2. 用剩余的N-K个元素依次与堆顶元素来比较,不满足则替换堆顶元素

        简单来说:以求取数组中前六个最大的元素为例,将一个元素个数为n的数组调整为大堆后,堆顶的元素就是数组中n个元素的最大值,获取堆顶元素后将堆顶元素删除(删除的步骤是堆顶元素先与堆尾元素交换,在堆尾删除堆顶元素),通过向下调整算法调整堆的结构使其仍然呈大堆排列,排列之后新的堆顶元素就是数组中n-1个元素中的最大值,依此类推。

  • 代码实现:
int a[] = { 1,2,3,5,4,9 };
int k;//前k个
scanf_s("%d", &k);
while (k--)
{printf("%d ", HPTop(&hp));HPPop(&hp);
}
  •  运行结果

2.面试中的Top_k问题

C语言:文件操作详解-CSDN博客

  • 给出N个整数,存储在磁盘文件中,要求取出最大的前k个元素。

        这个问题属于最常规的Top_k问题,建大堆然后依次popk个元素即可。但是面试中往往不会这么简单,这种方法固然存在一定的缺陷:当N过于大时,占用内存空间较多,如果给出10亿个整数就需要占用将近4G的内存空间,如果面试官对内存空间做出限制,显然这种方法就行不通了。

  • 给出N个整数,存储在磁盘文件中,要求取出最大的前k个元素且占用的内存空间不允许超过1KB。

        介绍一种很巧妙的方法:取前k个元素建小堆,然后用剩下的N-k个元素与堆顶元素比较,如果大于堆顶元素则直接覆盖堆顶元素,成为新的堆顶元素,最后用向下调整算法调整结构,依次遍历完所有的数据。这样留在堆中的元素就是最大的前k个元素。

//在text中创建N个数据
void CreateN()
{int n;scanf("%d", &n);srand((unsigned int)time(0));const char* FileName = "D:\\Git code\\data-structure\\Project_Heap\\Project_Heap\\data.txt";//文件地址FILE* fin = fopen(FileName, "w");if (fin == NULL) {perror("fopen fail");return;}for (int i = 1; i <= n; i++) {int x = (rand() + i) % 10000000;fprintf(fin, "%d\n", x);}fclose(fin);
}//Top_k
void Test3()
{CreateN();const char* FileName = "D:\\Git code\\data-structure\\Project_Heap\\Project_Heap\\data.txt";FILE* fout = fopen(FileName, "r");int k;scanf("%d", &k);int* kMinHeap = (int*)malloc(sizeof(int) * k);if (kMinHeap == NULL) {perror("malloc fail");return;}//将文件中的数据(前k个)读取到数组中for (int i = 0; i < k; i++) {fscanf(fout, "%d", &kMinHeap[i]);}//建堆for (int i = (k - 1 - 1) / 2; i >= 0; i--) {AdjustDown(kMinHeap, k, i);}int x;while (fscanf(fout, "%d", &x) > 0) {if (x > kMinHeap[0]) {kMinHeap[0] = x;AdjustDown(kMinHeap, k, 0);}}for (int i = 0; i < k; i++) {printf("%d\n", kMinHeap[i]);}fclose(fout);
}

四、堆排序

1.建堆

        给定一个数组,要求将其调整为大堆或小堆。我们可以将原数组直接看成一棵完全二叉树,然后利用向上或向下调整算法将其调整为大堆或小堆,大堆和小堆是可以自由切换的,只需要更改向下和向上调整算法中的比较逻辑即可。

  • 向上调整算法建小堆
int a[] = { 2,3,1,4,6,5,9 };
Heap hp;
HPInit(&hp);
int n = sizeof(a)/xizeof(int);
for (int i = 1; i < n; i++)AdjustUP(a, i);

        建堆逻辑:总是保证前i个数据具有堆的性质,当i=n时,整棵树都具有了堆的性质。


  • 向下调整算法建小堆
int a[] = { 2,3,1,4,6,5,9 };
Heap hp;
HPInit(&hp);
int n = sizeof(a)/sizeof(int);
for (int i = (n - 1 - 1) / 2; i < n; i++)AdjustDown(a, n, i);

        在向下调整算法建堆时,我们从倒数的第一个非叶子结点的子树开始调整,一直调整到根结点的树,就可以调整成堆。

        建堆逻辑:总是保持后i个数据具有堆的性质,当i=0时,整棵树都具有了堆的性质。


  • 图解(大根堆):

 2.堆排序

        堆排序即利用堆的思想来进行排序,总共分为两个步骤:

1. 建堆
  • 升序:建大堆
  • 降序:建小堆
2. 利用堆删除思想来进行排序:建堆和堆删除中都用到了向下调整,因此掌握了向下调整,就可以完成堆排序。
算法逻辑:以降序建小堆为例,一个元素个数为n的数组调整为小堆后,堆顶元素是数组中的最小元素,将堆顶元素与堆尾交换,然后对新的堆顶元素向下调整,一直调整到合适的位置再形成堆,此时堆顶元素应为数组中次小的元素,将次小的元素与第n-1个元素(倒数第二个)交换,再利用向下调整算法调整结构,依此类推。
代码实现:
//向下调整算法
void AdjustDown(HPDataType* a, int n, int parent)
{int child = 2 * parent + 1;while (child < n){if (child + 1 < n && a[child] > a[child + 1])child++;if (a[parent] > a[child]){Swap(&a[parent], &a[child]);parent = child;child = 2 * parent + 1;}elsebreak;}
}//交换
void Swap(HPDataType* a, HPDataType* b)
{HPDataType tmp = *b;*b = *a;*a = tmp;
}//堆排序(O(N*logN))
void HPSort(HPDataType* a, int n)
{//降序:建小堆//升序:建大堆//for (int i = 1; i < n; i++)//	AdjustUP(a, i);//向上调整建堆for (int i = (n - 1 - 1) / 2; i < n; i++)AdjustDown(a, n, i);int end = n - 1;while (end > 0){Swap(&a[0], &a[end]);AdjustDown(a, end, 0);--end;}
}

图解(升序大根堆):

五、堆的时间复杂度

1.建堆

a.树中高度与节点的关系

        设有一棵高度为h的满二叉树,如下图:

根据递推公式我们可以得到节点N与高度h的关系:F(h)=2^0+2^1+2^2+.....+2^(h-1)。根据等比数列求和公式,F(h)=2^h-1。


        一棵完全二叉树节点最多的情况是一棵满二叉树(最后一层全满),节点最少的情况是最后一层有且仅有一个节点的情况。

  • 满二叉树:F(h)=2^h-1=N——h=log(N+1)
  • 完全二叉树节点最少情况:F(h)=2^(h-1)=N——h=logN+1

        综上完全二叉树的节点应在log(N+1)与logN+1之间,根据大O的渐进表示法为logN。


b.向下调整建堆算法

        在向下调整建堆的过程中,我们选择从最后一个非叶子节点的节点开始调整,在计算时间复杂度时,只考虑最坏的情况,将堆简化看作一棵满二叉树,即每个双亲节点都需要调整到最底部,如第一层2^0个节点向下移动4次,第二层2^1个节点向下移动2层,第三层2^2个节点向下移动1次。

综上,向下调整建堆得时间复杂度为O(N)。

c.向上调整建堆算法

        在向上调整建堆中,我们选择从第一个子节点开始调整。还是只考虑最坏的情况并将堆简化为一棵满二叉树。从第2个节点开始,每个节点都需要向上调整高度次,即第二层2^1个节点向上移动1次,第三层2^2个节点向上移动2次,第四层2^3个节点(看作满二叉树)向上移动3次。

综上,向下调整建堆得时间复杂度为O(N*logN)。

 2.堆排序

建堆时间复杂度对比:

  • 向上调整建堆:O(N*logN)
  • 向下调整建堆:O(N)

堆排序的实现:

void HPSort(HPDataType* a, int n)
{//降序:建小堆//升序:建大堆//for (int i = 1; i < n; i++)//	AdjustUP(a, i);//向上调整建堆for (int i = (n - 1 - 1) / 2; i < n; i++)AdjustDown(a, n, i);int end = n - 1;while (end > 0){Swap(&a[0], &a[end]);AdjustDown(a, end, 0);--end;}
}

        建堆结束后,类比调整算法的推导可以得出排序的时间复杂度是O(N*logN)。  

相关文章:

【数据结构】第七节:堆

个人主页&#xff1a; 深情秋刀鱼-CSDN博客 数据结构专栏&#xff1a;数据结构与算法 源码获取&#xff1a;数据结构: 上传我写的关于数据结构的代码 (gitee.com) ​ 目录 一、堆 1.堆的概念 2.堆的定义 二、堆的实现 1.初始化和销毁 2.插入 向上调整算法 3.删除 向下调整算法…...

前端大师-高级Web开发测验

目录 前言 1.按正确的执行顺序排列脚本 2.哪些说法是正确的&#xff1f;&#xff08;D&#xff09; 3.填写正确的术语 4.程序的输出 5.将资源提示与其定义匹配 6.以下程序的输出是&#xff1f; 7.将PerformanceNavigationTimings按正确的顺序排列 8.将缓存指令与其定义…...

延迟初始化和密封类

Kotlin 延迟初始化&#xff08;Lazy Initialization&#xff09; 定义 在 Kotlin 中&#xff0c;延迟初始化允许你延迟一个对象的初始化&#xff0c;直到首次访问该对象时才进行初始化。这通常用于那些初始化开销较大&#xff0c;或者只在程序运行的某个特定点才需要的对象。…...

Kotlin基础之基本语法

Kotlin 简介 Kotlin 是一种由 JetBrains 开发的静态类型编程语言&#xff0c;设计用于与 Java 虚拟机 (JVM) 兼容&#xff0c;同时也可用于 Android、JavaScript&#xff08;通过 Kotlin/JS&#xff09;和原生&#xff08;通过 Kotlin/Native&#xff09;开发。Kotlin 旨在提供…...

多态(难的起飞)

注意 virtual关键字&#xff1a; 1、可以修饰原函数&#xff0c;为了完成虚函数的重写&#xff0c;满足多态的条件之一 2、可以菱形继承中&#xff0c;去完成虚继承&#xff0c;解决数据冗余和二义性 两个地方使用了同一个关键字&#xff0c;但是它们互相一点关系都没有 虚函…...

安装GO环境

#windows 1.下载go的安装包msi,下载完双击运行,指定一个目录进行安装 #msi安装时,会自动设置以下环境变量: #GOPATH(默认设置为C:\Users\hhx\go), #C:\Users\hhx\go\bin, #go安装位置下的bin目录 2.检查是否安装成功,终端中运行go version解释一些环境变量 GOROOT:go的安装位置…...

记一次由于代码原因导致Mysql连接被打满和唯一索引重复问题

先说一下事情产生的背景&#xff1a;原先的代码逻辑是消费MQ&#xff0c;然后请求其他服务的接口&#xff0c;对接口的返回值result做落库操作&#xff0c;现在要新加个逻辑&#xff0c;做完落库操作后还要再将result封装落到新表中&#xff1b;即消费一次MQ(MQ消息的频率非常高…...

redis数据类型之string,list

华子目录 key操作说明SCAN cursor [MATCH pattern] [COUNT count]dump与restorekeys 通配符 示例演示 string说明setbit key offset valuegetbit key offsetsetrange key offset value List结构图相关命令lrem key count valueltrim key count value示例&#xff1a;使用 LTRIM…...

Android android.os.DeadObjectException aidl通信异常分析及解决

问题描述 做一款音乐播放应用&#xff0c;播放服务是通过AIDL形式对外暴露&#xff0c;允许跨进程调用且多个App同时操作音乐播放&#xff0c;偶现android.os.DeadObjectException问题 12-15 09:28:12.371: W/System.err(5412): android.os.DeadObjectException 12-15 09:28:…...

dp + 计数,1954D - Colored Balls

一、题目 1、题目描述 2、输入输出 2.1输入 2.2输出 3、原题链接 Problem - 1954D - Codeforces 二、解题报告 1、思路分析 本题前置题目&#xff1a; 1953. 你可以工作的最大周数 通过前置题目可以知道如何计算两两不同数对序列的最大长度 我们记最大数量为ma&#xf…...

【设计模式深度剖析】【5】【结构型】【桥接模式】| 以电视和遥控器为例加深理解

&#x1f448;️上一篇:组合模式 设计模式-专栏&#x1f448;️ 目 录 桥接模式(Bridge Pattern)定义英文原话是&#xff1a;直译理解 4个角色UML类图代码示例 应用优点缺点使用场景 示例解析&#xff1a;电视和遥控器UML类图 桥接模式(Bridge Pattern) 定义 英文原话是&am…...

一键安装脚本sh

首先是初始化的ros安装的一些库&#xff1b; install.sh: execute_command() {if [ "$1" "1" ]; thenwget http://fishros.com/install -O fishros && bash fishroselif [ "$1" "2" ]; then#gnome-terminal --title"n…...

WebGL在医学成像方面的应用

WebGL&#xff08;Web Graphics Library&#xff09;是一种用于在Web浏览器中呈现3D和2D图形的JavaScript API。它被广泛应用于各种领域&#xff0c;包括医学成像。以下是WebGL在医学成像方面的应用及其详细描述。北京木奇移动技术有限公司&#xff0c;专业的软件外包开发公司&…...

SpringBoot+layuimini实现角色权限菜单增删改查(layui扩展组件 dtree)

角色菜单 相关组件方法效果图MySQL代码实现资源菜单树组件实现权限树方法js这里我先主要实现权限树的整体实现方法&#xff0c;如果是直接查看使用的话可以只看这里&#xff01; 后端代码Controlle层代码Service代码及实现类代码Service代码ServiceImpl代码 resourceMapper 代码…...

项目范围管理

目录 1.概述 2.主要工作 3.基础 4.项目范围管理的过程 5.规划范围管理 6.收集需求 7.定义范围 8.创建 WBS 9.确认范围 10.控制范围 1.概述 项目范围管理是项目管理中的一个重要组成部分&#xff0c;涉及到确定项目需要完成的工作范围&#xff0c;以及如何管理和控制…...

监管端..

文章目录 1. 登录流程2. 日志AOP 1. 登录流程 使用账号&#xff08;手机号&#xff09;、密码、验证码。登录就是获取token的&#xff0c;输入的账号密码用RSA加密&#xff08;非对称&#xff09; 首先输入账号密码&#xff0c;在发送手机验证码时候先校验账号密码有没有输入…...

点击登录按钮先检测输入框的规则检测(vue组合式)

<template><el-form :model"user" :rules"rules" ref"loginForm" label-width"auto" style"max-width: 600px"><el-form-item label"用户名" prop"name"><el-input v-model"…...

网络工程师---第四十二天

1、基于子网的vlan划分配置步骤是什么&#xff1f; 2、基于端口的vlan划分配置步骤是什么&#xff1f; 3、基于MAC地址的vlan划分配置步骤是什么&#xff1f; 4、请简述无线局域网的组网方式有哪几种&#xff0c;区别是什么&#xff1f; 5、请简述堆叠、级联和集群作用和区别是…...

leetcode 1241每个帖子的评论数(postgresql)

需求 编写 SQL 语句以查找每个帖子的评论数。 结果表应包含帖子的 post_id 和对应的评论数 number_of_comments 并且按 post_id 升序排列。 Submissions 可能包含重复的评论。您应该计算每个帖子的唯一评论数。 Submissions 可能包含重复的帖子。您应该将它们视为一个帖子。…...

前端最新面试题(ES6模块篇)

目录 1 ES5、ES6和ES2015有什么区别? 2 babel是什么,有什么作用? 3 let有什么用,有了var为什么还要用let? 4 举一些ES6对String字符串类型做的常用升级优化? 5 举一些ES6对Array数组类型做的常用升级优化 6 举一些ES6对Number数字类型做的常用升级优化 7 举一些ES…...

变量 varablie 声明- Rust 变量 let mut 声明与 C/C++ 变量声明对比分析

一、变量声明设计&#xff1a;let 与 mut 的哲学解析 Rust 采用 let 声明变量并通过 mut 显式标记可变性&#xff0c;这种设计体现了语言的核心哲学。以下是深度解析&#xff1a; 1.1 设计理念剖析 安全优先原则&#xff1a;默认不可变强制开发者明确声明意图 let x 5; …...

java 实现excel文件转pdf | 无水印 | 无限制

文章目录 目录 文章目录 前言 1.项目远程仓库配置 2.pom文件引入相关依赖 3.代码破解 二、Excel转PDF 1.代码实现 2.Aspose.License.xml 授权文件 总结 前言 java处理excel转pdf一直没找到什么好用的免费jar包工具,自己手写的难度,恐怕高级程序员花费一年的事件,也…...

解锁数据库简洁之道:FastAPI与SQLModel实战指南

在构建现代Web应用程序时&#xff0c;与数据库的交互无疑是核心环节。虽然传统的数据库操作方式&#xff08;如直接编写SQL语句与psycopg2交互&#xff09;赋予了我们精细的控制权&#xff0c;但在面对日益复杂的业务逻辑和快速迭代的需求时&#xff0c;这种方式的开发效率和可…...

第25节 Node.js 断言测试

Node.js的assert模块主要用于编写程序的单元测试时使用&#xff0c;通过断言可以提早发现和排查出错误。 稳定性: 5 - 锁定 这个模块可用于应用的单元测试&#xff0c;通过 require(assert) 可以使用这个模块。 assert.fail(actual, expected, message, operator) 使用参数…...

什么?连接服务器也能可视化显示界面?:基于X11 Forwarding + CentOS + MobaXterm实战指南

文章目录 什么是X11?环境准备实战步骤1️⃣ 服务器端配置(CentOS)2️⃣ 客户端配置(MobaXterm)3️⃣ 验证X11 Forwarding4️⃣ 运行自定义GUI程序(Python示例)5️⃣ 成功效果![在这里插入图片描述](https://i-blog.csdnimg.cn/direct/55aefaea8a9f477e86d065227851fe3d.pn…...

Python基于历史模拟方法实现投资组合风险管理的VaR与ES模型项目实战

说明&#xff1a;这是一个机器学习实战项目&#xff08;附带数据代码文档&#xff09;&#xff0c;如需数据代码文档可以直接到文章最后关注获取。 1.项目背景 在金融市场日益复杂和波动加剧的背景下&#xff0c;风险管理成为金融机构和个人投资者关注的核心议题之一。VaR&…...

tomcat入门

1 tomcat 是什么 apache开发的web服务器可以为java web程序提供运行环境tomcat是一款高效&#xff0c;稳定&#xff0c;易于使用的web服务器tomcathttp服务器Servlet服务器 2 tomcat 目录介绍 -bin #存放tomcat的脚本 -conf #存放tomcat的配置文件 ---catalina.policy #to…...

Golang——7、包与接口详解

包与接口详解 1、Golang包详解1.1、Golang中包的定义和介绍1.2、Golang包管理工具go mod1.3、Golang中自定义包1.4、Golang中使用第三包1.5、init函数 2、接口详解2.1、接口的定义2.2、空接口2.3、类型断言2.4、结构体值接收者和指针接收者实现接口的区别2.5、一个结构体实现多…...

windows系统MySQL安装文档

概览&#xff1a;本文讨论了MySQL的安装、使用过程中涉及的解压、配置、初始化、注册服务、启动、修改密码、登录、退出以及卸载等相关内容&#xff0c;为学习者提供全面的操作指导。关键要点包括&#xff1a; 解压 &#xff1a;下载完成后解压压缩包&#xff0c;得到MySQL 8.…...

用鸿蒙HarmonyOS5实现国际象棋小游戏的过程

下面是一个基于鸿蒙OS (HarmonyOS) 的国际象棋小游戏的完整实现代码&#xff0c;使用Java语言和鸿蒙的Ability框架。 1. 项目结构 /src/main/java/com/example/chess/├── MainAbilitySlice.java // 主界面逻辑├── ChessView.java // 游戏视图和逻辑├── …...