二叉树顺序结构及实现

👉二叉树顺序结构及实现

  • 1.二叉树的顺序结构
  • 2.堆的概念及结构
  • 3.堆的实现
    • 3.1堆向下调整算法
    • 3.2堆向上调整算法
  • 4.堆的创建
    • 4.1堆创建方法1
      • 4.1.1构建堆结构体
      • 4.1.2堆的初始化
      • 4.1.3堆数据添加+向上调整
      • 4.1.4主函数内容
    • 4.2堆的创建方法2
      • 4.2.1堆数据添加+向下调整
    • 4.3堆数据的删除
    • 4.4取根节点的数据
    • 4.5回收内存
    • 4.6Heap.h头文件展示
    • 4. 6Heap.c源文件展示
    • 4.7text.c源文件展示
  • 5.堆的用途
    • 5.1堆排序
    • 5.2 TopK问题

在这里插入图片描述

所属专栏:初始数据结构❤️
🚀 >博主首页:初阳785❤️
🚀 >代码托管:chuyang785❤️
🚀 >感谢大家的支持,您的点赞和关注是对我最大的支持!!!❤️
🚀 >博主也会更加的努力,创作出更优质的博文!!❤️
🚀 >关注我,关注我,关注我,重要的事情说三遍!!!!!!!!❤️

1.二叉树的顺序结构

普通的二叉树是不适合用数组来存储的,因为可能会存在大量的空间浪费。而完全二叉树更适合使用顺序结
构存储。现实中我们通常把堆(一种二叉树)使用顺序结构的数组来存储,需要注意的是这里的堆和操作系统 虚拟进程地址空间中的堆是两回事,一个是数据结构,一个是操作系统中管理内存的一块区域分段

  • 简单点解释一下上面的意思就是,我们一般用顺序结构来实现完全二叉树,而具体是实现方法就是我们把树中的节点都放到一个数组使其看起来是树的结构,但是存储方式是以数组的方式存储的。

我们用一张图片来清晰的理解一下。

在这里插入图片描述

  • 通过上面的两个图对比,只有完全二叉树才可以用顺序表存储,也只有这样才能体现出顺序表的特点——(连续存储数据)

2.堆的概念及结构

说到堆大家可能立马会想起我们操作系统虚拟进程地址空间,但是这里我们要讲的是,我们二叉树的堆和操作系统虚拟进程地址空间中的堆是两回事,我们二叉树中的堆是一种数据结构。

如果有一个关键码的集合K = { k0,k1 ,k2 ,…,k(n-1) },把它的所有元素按完全二叉树的顺序存储方式存储
在一个一维数组中,并满足:Ki <=K(2 * i+1) 且 Ki <= K(2 * i + 2) 或者 (Ki >=K(2 * i+1) 且 Ki >= K(2 * i + 2)) i = 0,1,
2…,则称为小堆(或大堆)。将根节点最大的堆叫做最大堆或大根堆,根节点最小的堆叫做最小堆或小根堆

堆的性质:

  • 堆中某个节点的值总是不大于或不小于其父节点的值;

  • 堆总是一棵完全二叉树

  • 用一句话总结就是:
    大堆就是一颗完全二叉树中的每一个节点的左右孩子都小于等于父节点
    小堆就是一颗完全二叉树中的每一个节点的左右孩子都大于等于父节点

在这里插入图片描述

3.堆的实现

3.1堆向下调整算法

  • 现在我们给出一个数组,逻辑上看做一颗完全二叉树。我们通过从根节点开始的向下调整算法可以把它调整
    成一个小堆。向下调整算法有一个前提:左右子树必须是一个堆,才能调整。

在这里插入图片描述

int arr[ ] = {1, 6, 5, 4, 3, 2 , 1} —— 调整前
int arr[ ] = {6, 4, 5, 1, 3, 2 , 1} ——调整后

3.2堆向上调整算法

  • 我们堆的向上调整也是需要左右节点是堆

在这里插入图片描述

4.堆的创建

4.1堆创建方法1

4.1.1构建堆结构体

  • 我们现在实现树的方式是顺序表,结合我们之前学习的顺序表,我们可以很快的想到我们要创建一个结构体,结构体包含了arr数组指针用来存放树的数据,size用来记录树节点当前的个数,capacity用来记录树的容量。
typedef int HPDataType;
typedef struct Heap
{HPDataType* a;int size;int capacity;
}HP;

4.1.2堆的初始化

  • 初始化就比较简单,刚开始我们的树就是为空的。
void HeapInit(HP* php)
{assert(php);php->size = php->capacity = 0;php->a = NULL;
}

4.1.3堆数据添加+向上调整

  • 我们实现堆的方式是顺序表,也就是说我们需要一个数组来存放树,所以我们就把数组当作是一颗树来进行。
    那么既然数组中存放着数据,那我们要怎么把一个乱序的数组给调整为一个堆呢?🤔这里我们先使用向上调整算法。
    于是我们就想到了,我们就把数组中的数据一个一个的放到树中,每当放一个进去的时候我们都进向上调整一下,这样我们每次进行向调整的时候都满足向上调整的要求(左右孩子是堆)。
void HeapPush(HP* php, HPDataType x)
{assert(php);//检查容量,和顺序表那章节是一样的这里就不多展开讲解了if (php->size == php->capacity){int newCapacity = php->capacity == 0 ? php->capacity = 4 : php->capacity * 2;HPDataType* tmp = (HPDataType*)realloc(php->a, sizeof(HPDataType) * newCapacity);if (tmp == NULL){perror("realloc fail");exit(-1);}else{php->a = tmp;php->capacity = newCapacity;}}//把数据放到树中php->a[php->size] = x;php->size++;//向上调整AdjustHeapUp(php->a, php->size - 1);
}
  • 而我们知道向上调整的条件是左右孩子是堆,这里我们以建大堆为例。只要我们的child大于我们的faster我么就向上调整,也就是child和faster进行交换,以此类推更新child和faster。
void Swap(int* a, int* b)
{HPDataType tmp = *a;*a = *b;*b = tmp;
}void AdjustHeapUp(HPDataType* a, int child)
{//怎么通过child求parent我们上一章节也见过了不明白的小伙伴可以再去看一看int parent = (child - 1) / 2;while (child > 0){if (a[child] > a[parent]){Swap(&a[child], &a[parent]);child = parent;parent = (child - 1) / 2;}//如果不符合我们直接跳出,因为如果不符合了就一定是形成了大堆,因为向上调整的条件就是左右孩子都是堆。else{break;}}
}

我们来画张图进行深入的剖析。
在这里插入图片描述

  • 其实上面的方法可以在优化一下,既然是通过一个一个的插入再向上调整的话,也就是说是按照数组的下标一次的向上调整,那我们不如一步到位直接将数组中的数据memcpy到树中,然后从通过一个for循环按照下标 的方式向上调整。
void HeapInitArr(HP* php, int* a, int n)
{assert(php);HPDataType* tmp = (HPDataType*)malloc(sizeof(HPDataType) * n);if (tmp == NULL){perror("realloc fail");exit(-1);}php->a = tmp;memcpy(php->a, a, sizeof(HPDataType) * n);php->size = n;php->capacity = n;for (int i = 1; i < n; i++ ){AdjustHeapUp(php->a, i);}
}

4.1.4主函数内容

int main()
{int a[] = { 56,89,2,33,6,2,55,6,9,33,8 };HP hp;HeapInit(&hp);//建造堆for (int i = 0; i < sizeof(a)/sizeof(HPDataType); i++){HeapPush(&hp, a[i]);//通过一个一个插入再向上调整建堆}HeapPrint(&hp);HeapDestry(&hp);return 0;
}

4.2堆的创建方法2

4.2.1堆数据添加+向下调整

  • 看到这里的小伙伴有没有发现,我们在建堆的时候,不仅在栈上开辟了一个数组用来存放要插入树中的数据,还在堆区开辟了一块内存表示树,但是有没有发现其实这两个地方本质上都是数组,那为什么还要开辟堆上的内存呢?直接在数组上进行不就行了?于是我们就有了向下调整。

  • 我们建堆除了用向上调整还可以用向下调整,假想一下我们用向上调整的方法用到向下调整上会是怎么样的。也就是说我们每插入一个数据就向下调整,但是这显然是行不通的,因为插入一个数据后,后面根本就没有数据了,何来的向下调整。于是我们不能和向上调整一样一个一个数据的插入,而是直接在数组上进行调整。那么问题也来了,向下调整也是要求左右孩子是堆才能进行的,如果我们从根节点开始的话就不满足条件了,所以我们从最后一个节点的度不为0的节点开始向上调整就行了而当我我们调整好了当前节点之后需要调整下一个节点的时候只需要当前节点减减就可以找到另一个需要调整的节点就行了。

void Swap(int* a, int* b)
{int tmp = *a;*a = *b;*b = tmp;
}void AdjustDown(HPDataType* a, int n, int parent)
{assert(a);//先假设左左孩子int child = parent * 2 + 1;while (child < n){//判断是右孩子小还是左孩子小//注意有可能不是满二叉树,可能只有左孩子没有右孩子,所以要判断child + 1 < n;if (child + 1 < n && a[child + 1] > a[child]){++child;}//判断parent是否小于孩子if (a[parent] < a[child]){Swap(&a[parent], &a[child]);//更新parentparent = child;child = parent * 2 + 1;}else{break;}}
}int main()
{int a[] = { 56,89,2,33,6,2,55,6,9,33,8 };HP hp;int len = sizeof(a) / sizeof(int);//解释一下(len-2)/ 2: len是数组的长度,但是我们操作的是下标所以说是len - 1,//而我们最后一个度不为0的节点的孩子节点肯定是包含了最后一个叶子节点,所以显然可以求出最后一个度不为0 的节点就是(len - 1 - 1)  / 2for (int i = (len -  1 - 1) / 2; i >= 0; i--){AdjustDown(a, len - 1, i);}for (int i = 0; i < len; i++){printf("%d ", a[i]);}return 0;
}
  • 如果这里你看明白了,相信你也发现了,我们的向上调整也是可以这样做的,这里就留给小伙伴们自行思考了,如果有任何问题都可以在在评论区中提问的哦。

4.3堆数据的删除

⚠️⚠️注:这里我们还是使用第一种建堆的方法。

  • 既然我们建好了堆,我们要删除堆的数据,如果说只是删除堆的最后一个数据那就显得很没有意义,所以我们删除堆的数据是删除根节点的数据。设想一下,如果我们直接删除根节点的树后,因为我们是使用顺序表存放树的数据的,直接暴力删除根节点就会破坏我们原先建好的堆结构,如果我们还要有堆的结构的话我们就对再次通过建堆的方式重新建堆这无疑是一件大工程。那么有什么好的方法可以做到既删除数据,还可以保留堆的结构呢?于是我们就想到了可以讲根节点与最后一个叶子节点进行交换,然后再删除尾,再做一次向下调整就行了。
void HeapPop(HP* php)
{assert(php);assert(!HeapEmpty(php));Swap(&php->a[0], &php->a[php->size - 1]);php->size--;AdjustDown(php->a, php->size - 1, 0);
}

4.4取根节点的数据

HPDataType HeapTop(HP* php)
{assert(php);return php->a[0];
}

4.5回收内存

这个讲了很多遍了,这里就简单略过。

void HeapDestry(HP* php)
{assert(php);free(php->a);php->a = NULL;php->size = php->capacity = 0;
}

4.6Heap.h头文件展示

#pragma once
#include <stdio.h>
#include <stdlib.h>
#include <assert.h>
#include <stdbool.h>typedef int HPDataType;
typedef struct Heap
{HPDataType* a;int size;int capacity;
}HP;	
void AdjustDown(HPDataType* a, int n, int parent);
void AdjustHeapUp(HPDataType* a, int child);
void Swap(int* a, int* b);void HeapPrint(HP* php);
void HeapInit(HP* php);
void HeapInitArr(HP* php, int * a, int n);
void HeapDestry(HP* php);
void HeapPush(HP* php, HPDataType x);
void HeapPop(HP* php);
HPDataType HeapTop(HP* php);

4. 6Heap.c源文件展示

#define _CRT_SECURE_NO_WARNINGS 1
#include "deap.h"void HeapInit(HP* php)
{assert(php);php->size = php->capacity = 0;php->a = NULL;
}void HeapInitArr(HP* php, int* a, int n)
{assert(php);HPDataType* tmp = (HPDataType*)malloc(sizeof(HPDataType) * n);if (tmp == NULL){perror("realloc fail");exit(-1);}php->a = tmp;memcpy(php->a, a, sizeof(HPDataType) * n);php->size = n;php->capacity = n;for (int i = 1; i < n; i++ ){AdjustHeapUp(php->a, i);}
}void HeapDestry(HP* php)
{assert(php);free(php->a);php->a = NULL;php->size = php->capacity = 0;
}
void Swap(int* a, int* b)
{HPDataType tmp = *a;*a = *b;*b = tmp;
}void AdjustHeapUp(HPDataType* a, int child)
{int parent = (child - 1) / 2;while (child > 0){if (a[child] > a[parent]){Swap(&a[child], &a[parent]);child = parent;parent = (child - 1) / 2;}else{break;}}
}void HeapPush(HP* php, HPDataType x)
{assert(php);//检查容量if (php->size == php->capacity){int newCapacity = php->capacity == 0 ? php->capacity = 4 : php->capacity * 2;HPDataType* tmp = (HPDataType*)realloc(php->a, sizeof(HPDataType) * newCapacity);if (tmp == NULL){perror("realloc fail");exit(-1);}else{php->a = tmp;php->capacity = newCapacity;}}php->a[php->size] = x;php->size++;//向上调整AdjustHeapUp(php->a, php->size - 1);
}void HeapPrint(HP* php)
{assert(php);for (int i = 0; i < php->size; i++){printf("%d ", php->a[i]);}
}void AdjustDown(HPDataType* a, int n, int parent)
{assert(a);//先假设左左孩子int child = parent * 2 + 1;while (child < n){//判断是右孩子小还是左孩子小//注意有可能不是满二叉树,可能只有左孩子没有右孩子,所以要判断child + 1 < n;if (child + 1 < n && a[child + 1] > a[child]){++child;}//判断parent是否小于孩子if (a[parent] < a[child]){Swap(&a[parent], &a[child]);//更新parentparent = child;child = parent * 2 + 1;}else{break;}}
}void HeapPop(HP* php)
{assert(php);assert(!HeapEmpty(php));Swap(&php->a[0], &php->a[php->size - 1]);php->size--;AdjustDown(php->a, php->size - 1, 0);
}HPDataType HeapTop(HP* php)
{assert(php);return php->a[0];
}

4.7text.c源文件展示

int main()
{int a[] = { 56,89,2,33,6,2,55,6,9,33,8 };HP hp;HeapInit(&hp);//建造堆for (int i = 0; i < sizeof(a)/sizeof(HPDataType); i++){HeapPush(&hp, a[i]);}HeapPrint(&hp);printf("\n");//这样就可以打印出一个排完序的数据while (!HeapEmpty(&hp)){printf("%d ", HeapTop(&hp));HeapPop(&hp);}HeapDestry(&hp);return 0;
}

5.堆的用途

5.1堆排序

  • 堆的用途之一就是进行堆排序,那么如果我们得到一个升序的数组的话我我们应该建大堆还是小堆呢?🤔我相信大部分人的第一反应就是建小堆,为什么呢,因为如果是小堆的话,我们就可以找到堆中最小的那个数据,然后通过在创建一个数组的方式以及堆Top的方法把最小的放到新建的数组中,固然这是一个方法,但是不是一个好方法,我们能不能就再原数组中进行排序呢?🤔答案是可以的,这时我们建的是大堆。我们的思路是建好一个大堆后,把最后一个叶子节点和根节点进行交换交换后我们的树的节点个数减1,然后进行向下调整,这个时候我们的数组中最大的数到了最后一个并且向下调整的时候不参与调整,以此类推知道数的节点个数为0为止我们就排好序了。
void sort(int* a, int n)
{//把数组直接看成是一个对,然后对其进行向上调整,得到大堆//升序建大堆,降序建小堆int i = 0;for (int i = 1; i < n; i++){AdjustHeapUp(a, i);}int end = n - 1;while (end > 0){Swap(&a[0], &a[end]);//向下调整AdjustDown(a, end, 0);end--;}
}int main()
{int a[] = { 56,89,2,33,6,2,55,6,9,33,8 };sort(a, sizeof(a) / sizeof(int));for (int i = 0; i < sizeof(a) / sizeof(int); i++){printf("%d ", a[i]);}
}

在这里插入图片描述

相反的如果要弄降序就建小堆。

5.2 TopK问题

  • 所谓TopK就是取出前K个最大的数,或者后K个最小的数。
    这里就那取出前K个最大的数来举例子,而且是以文件的形式进行存储。

  • 假如有n个数据,找出前k个最大的数据。

  • 我们的方法就是:
    1️⃣ .先创建一个节点个数为K的小堆
    2️⃣ .一次遍历n-k个数据
    3️⃣ .每次遍历后都与根节点比较,如果大于根节点就是根节点等于该数据,再进行向下调整

#define _CRT_SECURE_NO_WARNINGS 1
#include <stdio.h>
#include <string.h>
#include <time.h>
#include <stdlib.h>//HeapTopK问题,找出数据中前k个大的数据
//步骤:
// 1.先创建k个节点的堆(如果是找前k的大的数据就建小堆,如果是找前k个小的就建大堆)
// 2.然后用剩下的数据和堆的根比较,如果比根大就替换,然后向下调整
// 3.遍历完毕后堆中的数据就是想要的结果了。const int N = 10000;void CreatData()
{//设置随机种子srand((unsigned int)time(NULL));const char* file_name = "data.txt";//将数据写到文件中FILE* file = fopen(file_name, "w");if (file == NULL){perror("fopen file");return;}for (int i = 0; i < N; i++){int x = rand() % 1000000;fprintf(file, "%d\n", x);}fclose(file);
}void Swap(int* a, int* b)
{int tmp = *a;*a = *b;*b = tmp;
}void AdjustDown(int* a, int k ,int parent)
{int child = parent * 2 + 1;while (child < k){if (child + 1 < k && a[child + 1] < a[child]){child++;}if (a[parent] > a[child]){Swap(&a[parent], &a[child]);parent = child;child = parent * 2 + 1;}else{break;}}
}void print_topK(int k)
{int arr1[10000];//首先把文件中的前k个数据放到堆中,创建小堆FILE* file = fopen("data.txt", "r");//创建存放堆的顺序表int* arr2 = (int*)malloc(sizeof(int) * k);if (arr2 == NULL){perror("malloc");return;}for (int i = 0; i < N; i++){int x = 0;fscanf(file, "%d", &x);arr1[i] = x;}//把前k个数据放到arr中for (int i = 0; i < k; i++){arr2[i] = arr1[i];}//向下调整,形成小堆for (int i = (k - 2) / 2; i >= 0; i--){AdjustDown(arr2,k, i);}//遍历剩下的数据for (int i = k; i < N; i++){if (arr2[0] < arr1[i]){arr2[0] = arr1[i];AdjustDown(arr2, k, 0);}}for (int i = 0; i < k; i++){printf("%d ", arr2[i]);}fclose(file);
}int main()
{int k = 10;//创建10000个数据放到文件中//CreatData();print_topK(10);
}

在这里插入图片描述

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

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

相关文章

Oracle两个日期都存在返回最小/最大的,如果只存在一个就返回存在的日期

Oracle函数 Oracle两个字段日期都存在返回最小的&#xff0c;如果只存在一个就返回存在的日期. 函数说明LEAST(value1, value2, …)最小值GREATEST(value1, value2, …)最大值COALESCE(value1, value2, …)返回第一个不是空值的参数

CAN总线

can总线看起来和485电路很相似&#xff0c;485出来是AB 线&#xff0c;can出来 CAN_HIGH CAN_LOW 2.CAN总线特点 多主控制不像iic 只能一个主机&#xff0c;也没有地址的概念

ModuleNotFoundError: No module named ‘transformers.modeling_bert‘解决方案

大家好,我是爱编程的喵喵。双985硕士毕业,现担任全栈工程师一职,热衷于将数据思维应用到工作与生活中。从事机器学习以及相关的前后端开发工作。曾在阿里云、科大讯飞、CCF等比赛获得多次Top名次。现为CSDN博客专家、人工智能领域优质创作者。喜欢通过博客创作的方式对所学的…

【Linux旅行记】探究操作系统是如何进行管理的!

文章目录 什么是操作系统&#xff1f;操作系统概念操作系统的目的底层硬件驱动程序操作系统理解系统调用接口 操作系统是如何进行管理的&#xff1f;什么是管理&#xff1f;操作系统是如何管理硬件信息呢&#xff1f; &#x1f340;小结&#x1f340; &#x1f389;博客主页&am…

数据结构——线性表之顺序表

目录 一.线性表 二.顺序表实现 2.1 概念及结构 2.2 动态顺序表 2.2.1 初始化与销毁函数 2.2.2 打印函数 2.2.3 尾插函数 2.2.4 尾删函数 2.2.5 扩容函数 2.2.6 头插函数 2.2.7 头删函数 2.2.8 任意位置插入函数 2.2.9 查找函数 2.2.10 任意位置删除函数 2.2.11 修…

基于Java体育馆管理系统设计实现(源码+lw+部署文档+讲解等)

博主介绍&#xff1a;✌全网粉丝30W,csdn特邀作者、博客专家、CSDN新星计划导师、Java领域优质创作者,博客之星、掘金/华为云/阿里云/InfoQ等平台优质作者、专注于Java技术领域和毕业项目实战✌ &#x1f345;文末获取源码联系&#x1f345; &#x1f447;&#x1f3fb; 精彩专…

RFID车辆自动化称重管理

应用背景 随着物流和交通管理的发展&#xff0c;车辆称重成为了不可忽视的环节&#xff0c;传统的车辆称重管理方式存在诸多问题&#xff0c;如人工操作繁琐、数据准确性低、容易出现作弊等&#xff0c;为了提高车辆称重管理的效率和准确性&#xff0c;RFID技术被引入到车辆称…

使用Langchain+GPT+向量数据库chromadb 来创建文档对话机器人

使用LangchainGPT向量数据库chromadb 来创建文档对话机器人 一.效果图如下&#xff1a; 二.安装包 pip install langchainpip install chromadbpip install unstructuredpip install jieba三.代码如下 #!/usr/bin/python # -*- coding: UTF-8 -*-import os # 导入os模块&…

为什么2022年秋招嵌入式开发岗位薪资大涨?

今天看到一个网友讨论的问题&#xff0c;其实这个问题也很简答。从嵌入式本身优势来说&#xff0c;首先是因为该行业人才人才需求大&#xff0c;据权威统计机构统计在所有软件开发类人才的需求中&#xff0c;对嵌入式工程师的需求达到全部需求量的60%~80%&#xff0c;并且每年以…

数据结构(C语言)——双链表

有了单链表的编写经验&#xff0c;双链表变得格外容易。点击看前一篇-单链表 下面是代码&#xff1a; #include<stdio.h> #include<stdlib.h> #define E int typedef struct node {E element;struct node* pre;struct node* next; }node; void initialise(node* h…

JavaScript中的`async`和`await`关键字的作用

聚沙成塔每天进步一点点 ⭐ 专栏简介⭐ async关键字⭐ await 关键字3. 错误处理 ⭐ 写在最后 ⭐ 专栏简介 前端入门之旅&#xff1a;探索Web开发的奇妙世界 记得点击上方或者右侧链接订阅本专栏哦 几何带你启航前端之旅 欢迎来到前端入门之旅&#xff01;这个专栏是为那些对We…

selenium中ActionChains方法详细讲解

前言 本文将介绍Selenium中的ActionChains类及其使用方法&#xff0c;帮助您模拟用户在网页上的鼠标和键盘操作。了解ActionChains的常用方法和示例代码&#xff0c;可轻松实现移动鼠标、点击元素、拖拽元素等操作。通过本文的学习&#xff0c;您能更好地应用ActionChains解决自…

nginx中sent_timeout属性使用注意事项

send_timeout使用注意事项 send_timeout:指客户端向服务器发送请求并且等待服务器返回数据的时间&#xff0c;超过这个时间链接就断开。如果咱们返回的数据复杂&#xff0c;很耗时&#xff0c;就将该值设置大些。注意该时间指准备过程&#xff0c;不是传输过程&#xff08;下载…

Python基础指令(上)

Python基础指令上 常量和表达式变量和类型1. 什么是变量2. 变量的语法2.1 定义变量2.2 使用变量 3. 变量的类型4. 为什么要有这么多类型5. 动态类型特性 注释输入输出1. 程序与用户的交互2. 通过控制台输出3. 通过控制台输入 运算符1. 算术运算符2. 关系运算符3. 逻辑运算符4. …

Linux文件出现“M-oM-;M-?” ^M 等情况

1、当在编辑linux系统的文件时&#xff0c;会出现如下情况&#xff1a; 解决方法&#xff1a;单个文件可以使用vim 进行修改&#xff0c;shift :&#xff0c; 然后 set nobomb 2、当文件出现每一行末尾^M的情况&#xff1a; 解决方法&#xff1a;使用vi的替换功能。启动vi&am…

vue使用swiper轮播组件开启loop模式点击不了问题处理

1.原本在这里的点击事件换成 :data-href"func_str(item)" 2.在methods里面写好方法 func_str(item){ return JSON.stringify(item); } 3.在原本的调用调用轮播图方法里面加入点击事件 onClick:function(swiper){ var item JSON.parse(swiper.clickedSlide.attrib…

随手笔记(四十五)——idea git冲突

图片为引用&#xff0c;在一次导入项目至gitee的过程中&#xff0c;不知道为什么报了403&#xff0c;很奇怪的一个错误&#xff0c;网上很多的答案大概分成两种。 第一种是最多的&#xff0c;直接找到windows凭据删掉 很抱歉的告诉各位&#xff0c;你们很多人到这里就已经解…

相机HAL

相机HAL 1、概览实现 HAL2、相机 HAL2.1 AIDL 相机 HAL2.2 相机 HAL3 功能2.3 Camera HAL1 概览 相机 HAL 相机 实现 HAL android12-release 1、概览实现 HAL HAL 位于 相机驱动程序 和 更高级别的 Android 框架 之间&#xff0c;它定义您必须实现的接口&#xff0c;以便应用…

php高级 TP+Redis实现发布订阅和消息推送案例实战

Redis 的发布-订阅模型是一种消息通信模式&#xff0c;它允许客户端之间通过特定的频道进行通信。在这种模型中&#xff0c;有些客户端负责发布消息&#xff08;发布者&#xff09;&#xff0c;而其他客户端则订阅它们感兴趣的频道并接收这些消息&#xff08;订阅者&#xff09…

机器学习入门与实践:从原理到代码

&#x1f482; 个人网站:【工具大全】【游戏大全】【神级源码资源网】&#x1f91f; 前端学习课程&#xff1a;&#x1f449;【28个案例趣学前端】【400个JS面试题】&#x1f485; 寻找学习交流、摸鱼划水的小伙伴&#xff0c;请点击【摸鱼学习交流群】 在本文中&#xff0c;我…