二叉树和堆

目录

1.二叉树的概念及结构

1.1概念

1.2特殊的二叉树

1.3二叉树的性质

1.4二叉树的存储结构

2.二叉树的顺序结构及实现(堆)

2.1二叉树的顺序结构

2.2堆的概念及结构

2.3堆的实现

2.3.1堆的插入

2.3.2堆的删除

2.3.3 Heap.h

2.3.4 Heap.c

2.3.5 test.c

2.4堆的创建

2.4.1建堆的时间复杂度

1.向下调整算法:

2.向上调整算法:

2.5堆的应用

2.5.1堆排序

2.5.2 TOP-K问题

3.二叉树链式结构的实现

3.1二叉树的遍历

3.1.1 前序、中序及后序的遍历

3.1.2节点个数及高度

3.1.3二叉树的销毁

3.1.4层序遍历

3.1.5判断二叉树是否为完全二叉树

3.2二叉树的oj


1.二叉树的概念及结构

1.1概念

一颗二叉树是节点的一个有限集合,该集合:

        1.或者为空

        2.由一个根节点加上两颗别称为左子树和右子树的二叉树组成

从上图可以看出:

1.二叉树不存在度大于2的节点

2.二叉树的子树有左右之分,次序不能颠倒,因此二叉树是有序树。

注意:对于任意的二叉树都是由以下几种情况复合而成:

1.2特殊的二叉树

1.满二叉树:一个二叉树,如果每一层得节点数都达到最大值,则这个二叉树就是满二叉树。也就是说,如果一个二叉树的层数为k,且节点总数是2^k-1,则它就是满二叉树。

2.完全二叉树:完全二叉树是效率很高的数据结构,完全二叉树是由满二叉树而引出来的。对于深度为k的,有n个节点的二叉树当且仅当每一个节点都与深度为k的满二叉树中编号从1至n的节点一一对应时称为完全二叉树。注意的是满二叉树是一种特殊的完全二叉树。

1.3二叉树的性质

1. 若规定根结点的层数为 1 ,则一棵非空二叉树的 i 层上最多有2^{(i-1)}个结点.
2. 若规定根结点的层数为 1 ,则 深度为 h 的二叉树的最大结点数是2^{h}-1
3. 对任何一棵二叉树 , 如果度为 0的 叶结点个数为n0  , 度为 2 的分支结点个数为n2  , 则有 n0=n2 + 1
/*
* 假设二叉树有 N 个结点
* 从总结点数角度考虑: N = n0 + n1 + n2    ①
*
* 从边的角度考虑, N 个结点的任意二叉树,总共有 N-1 条边
* 因为二叉树中每个结点都有双亲,根结点没有双亲,每个节点向上与其双亲之间存在一条边
* 因此 N 个结点的二叉树总共有 N-1 条边
* 因为度为 0 的结点没有孩子,故度为 0 的结点不产生边 ; 度为 1 的结点只有一个孩子,故每个度为 1 的结点 产生一条边 ; 度为 2 的结点有 2 个孩子,故每个度为 2 的结点产生两条边,所以总边数为: n1+2*n2
* 故从边的角度考虑: N-1 = n1 + 2*n2 ②
* 结合 得: n0 + n1 + n2 = n1 + 2*n2 - 1
* 即: n0 = n2 + 1
*/
4. 若规定根结点的层数为 1 ,具有 n 个结点的满二叉树的深度 h=\log_{2}(n+1)
5. 对于具有 n 个结点的完全二叉树,如果按照从上至下从左至右的数组顺序对所有结点从 0 开始编号,则对于序号为i 的结点有:
1. i>0 i 位置结点的双亲序号: (i-1)/2 i=0 i 为根结点编号,无双亲结点
2. 2i+1<n ,左孩子序号: 2i+1 2i+1>=n 否则无左孩子
3. 2i+2<n ,右孩子序号: 2i+2 2i+2>=n 否则无右孩子

1.4二叉树的存储结构

二叉树一般可以使用两种结构存储,一种是顺序结构,一种是链式结构

1.顺序存储


 顺序结构存储就是使用数组来存储,一般使用数组只适合表示完全二叉树,因为不是完全二叉树会有空间浪费。而现实中使用只有堆才会用数组来存储。二叉树顺序存储在物理上是一个数组,在逻辑上是一颗二叉树。


2.链式存储

二叉树的链式存储结构是指用链表来表示一颗二叉树,即用链表来表示元素的逻辑关系。通常方法是链表中每个节点由三个域组成,数据域和左右指针,左右指针分别用来给出该节点的左孩子和右孩子所在的链结点的存储地址。链式结构又分为二叉链和三叉链。

typedef int BTDataType;
//二叉链
struct BinaryTreeNode
{struct BinaryTreeNode* left;struct BinaryTreeNode* right;BTDataType data;
};
//三叉链
struct BinaryTreeNode
{struct BinaryTreeNode* parent;struct BinaryTreeNode* left;struct BinaryTreeNode* right;BTDataType data;
};

2.二叉树的顺序结构及实现(堆)

2.1二叉树的顺序结构

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

2.2堆的概念及结构

堆的性质:
  • 堆中某个节点的值总是不大于或小于其父节点的值;
  • 堆总是一颗完全二叉树。

2.3堆的实现

2.3.1堆的插入

先插入一个10到数组的尾上,再进行向上调整算法,直到满足堆。

void Swap(HPDataType* p1, HPDataType* p2)
{HPDataType temp =*p1;*p1 = *p2;*p2 = temp;
}void AdjustUp(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(Heap* hp, HPDataType x)//插入
{if (hp->capacity == hp->size){int newcapacity = hp->capacity == 0 ? 4 : 2 * hp->capacity;hp->capacity = newcapacity;HPDataType* temp = (HPDataType*)realloc(hp->a, hp->capacity * sizeof(HPDataType));if (temp == NULL){perror("realloc fail");return;}hp->a = temp;}hp->a[hp->size] = x;hp->size++;AdjustUp(hp->a, hp->size - 1);
}

2.3.2堆的删除

删除堆是删除堆顶的数据,将堆顶的数据根最后一个数据一换,然后删除数组最后一个数据,再进行向下调整算法。

void AdjustDown(HPDataType* a, int n, int parent)
{int child = parent * 2 + 1;while (child < n){if (child + 1 < n && a[child] > a[child + 1]){child = child + 1;}if (a[child] < a[parent]){Swap(&a[child], &a[parent]);parent = child;child = parent * 2 + 1;}else{break;}}
}void HeapPop(Heap* hp)//删除
{assert(hp);assert(hp->size > 0);Swap(&hp->a[0], &hp->a[hp->size - 1]);hp->size--;AdjustDown(hp->a, hp->size, 0);
}

2.3.3 Heap.h

#pragma once
#include<stdio.h>
#include<stdlib.h>
#include<stdbool.h>
#include<assert.h>//typedef int BTDataType;
二叉链
//struct BinaryTreeNode
//{
//	struct BinaryTreeNode* left;
//	struct BinaryTreeNode* right;
//	BTDataType data;
//};
三叉链
//struct BinaryTreeNode
//{
//	struct BinaryTreeNode* parent;
//	struct BinaryTreeNode* left;
//	struct BinaryTreeNode* right;
//	BTDataType data;
//};
typedef int HPDataType;typedef struct Heap
{HPDataType* a;int size;int capacity;
}Heap;void HeapInit(Heap* hp);//初始化void HeapDestory(Heap* hp);//销毁void HeapPush(Heap* hp, HPDataType x);//插入void HeapPop(Heap* hp);//删除HPDataType HeapTop(Heap* hp);//取堆顶数据int HeapSize(Heap* hp);//数据个数bool HeapEmpty(Heap* hp);//判空void AdjustUp(HPDataType* a, int child);void AdjustDown(HPDataType* a, int n, int parent);void Swap(HPDataType* p1, HPDataType* p2);

2.3.4 Heap.c

#include"heap.h"
void HeapInit(Heap* hp)//初始化
{assert(hp);hp->a = NULL;hp->capacity = hp->size = 0;
}void HeapDestory(Heap* hp)//销毁
{assert(hp);free(hp->a);hp->a = NULL;hp->capacity = hp->size = 0;
}void Swap(HPDataType* p1, HPDataType* p2)
{HPDataType temp =*p1;*p1 = *p2;*p2 = temp;
}void AdjustUp(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(Heap* hp, HPDataType x)//插入
{if (hp->capacity == hp->size){int newcapacity = hp->capacity == 0 ? 4 : 2 * hp->capacity;hp->capacity = newcapacity;HPDataType* temp = (HPDataType*)realloc(hp->a, hp->capacity * sizeof(HPDataType));if (temp == NULL){perror("realloc fail");return;}hp->a = temp;}hp->a[hp->size] = x;hp->size++;AdjustUp(hp->a, hp->size - 1);
}void AdjustDown(HPDataType* a, int n, int parent)
{int child = parent * 2 + 1;while (child < n){if (child + 1 < n && a[child] > a[child + 1]){child = child + 1;}if (a[child] < a[parent]){Swap(&a[child], &a[parent]);parent = child;child = parent * 2 + 1;}else{break;}}
}void HeapPop(Heap* hp)//删除
{assert(hp);assert(hp->size > 0);Swap(&hp->a[0], &hp->a[hp->size - 1]);hp->size--;AdjustDown(hp->a, hp->size, 0);
}HPDataType HeapTop(Heap* hp)//取堆顶数据
{assert(hp);assert(hp->size > 0);return hp->a[0];
}
int HeapSize(Heap* hp)//数据个数
{assert(hp);return hp->size;
}bool HeapEmpty(Heap* hp)//判空
{assert(hp);return hp->size == 0;
}

2.3.5 test.c

#include"heap.h"void test1()
{int a[] = { 1,5,33,7,4,32,6,3,8,9,2 };Heap hp;HeapInit(&hp);for (int i = 0; i < sizeof(a) / sizeof(int); i++){HeapPush(&hp, a[i]);}while (!HeapEmpty(&hp)){printf("%d ", HeapTop(&hp));HeapPop(&hp);}HeapDestory(&hp);
}int main()
{test1();return 0;
}

2.4堆的创建

下面我们给出一个数组,这个数组逻辑上可以看做一颗完全二叉树,但是还不是一个堆,现在我们通过算法,把它构建成一个堆。根结点左右子树不是堆,我们怎么调整呢?这里我们从倒数的第一个非叶子结点的子树开始调整,一直调整到根结点的树,就可以调整成堆。
如:int a[] = {1,5,3,8,7,6}

2.4.1建堆的时间复杂度

因为堆是完全二叉树,而满二叉树也是完全二叉树,此处为了简化使用满二叉树来证明 ( 时间复杂度本来看的就是近似值,多几个结点不影响最终结果)
1.向下调整算法:

向下调整算法的时间复杂度为O(N)。

2.向上调整算法:

向上调整算法时间复杂度为O(N*logN)。

2.5堆的应用

2.5.1堆排序

1.建堆

  • 升序:建大堆
  • 降序:建小堆

2.利用堆删除的思想来进行排序

void HeapSort(HPDataType* a, int n)
{//建堆从非叶子节点开始//降序建小堆for (int i = (n - 1 - 1) / 2; i >= 0; i--){AdjustDown(a, n, i);}int end = n - 1;while (end){Swap(&a[0], &a[end]);AdjustDown(a, end, 0);end--;}
}void test2()
{int a[] = { 1,5,33,7,4,32,6,3,8,9,2 };HeapSort(a, sizeof(a) / sizeof(int));for (int i = 0; i < sizeof(a) / sizeof(int); i++){printf("%d ", a[i]);}
}int main()
{test2();return 0;
}

2.5.2 TOP-K问题

TOP-K问题:即求数据中前k个最大的元素或者最小的元素,一般情况下数据量比较大。
比如:专业前10名,世界500强,富豪榜等。
对于TOP-K问题来说最简单直接的方法是排序,但是如果数据量非常大,排序就不太可取了(可能数据不能一下全部加载到内存中)。最佳的方式是堆来解决,基本思路如下:

     1.用数据的前K个元素建堆

找前K个最大的元素,建小堆。
找前K个最小的元素,建大堆。
2.将后N-K个元素依次与堆顶元素比较,不满足则替换堆顶数据
void CreatNode()
{int n = 100000;srand((unsigned)time(NULL));const char* file = "data.txt";FILE* fin = fopen(file, "w");if (fin == NULL){perror("fopen error");return;}for (int i = 0; i < n; i++){int x = (rand() + i) % 100000000;//+i防止重复数过多,并且数的大小不超过一亿fprintf(fin, "%d\n", x);}fclose(fin);
}void TopK()
{int k = 0;printf("请输入k>");scanf("%d", &k);int* kminheap = (int*)malloc(sizeof(int) * k);if (kminheap == NULL){perror("malloc fail");return;}const char* file = "data.txt";FILE* fout = fopen(file, "r");if (fout == NULL){perror("fout fail");}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 = 0;while (fscanf(fout, "%d", &x) != EOF){if (x > kminheap[0]){kminheap[0] = x;AdjustDown(kminheap, k, 0);}}for (int i = 0; i < k; i++){printf("%d ", kminheap[i]);}printf("\n");
}int main()
{// CreatNode();TopK();return 0;
}

3.二叉树链式结构的实现

二叉树是:

  1. 空树。
  2. 非空:根节点,根节点的左子树,根节点的右子树组成的。

3.1二叉树的遍历

3.1.1 前序、中序及后序的遍历

所谓二叉树遍历是按照某种特定的规则,依次对二叉树中的节点进行对应的操作,并且每个节点只操作一次。按照规则,二叉树的遍历有:前序/中序/后序的递归结构遍历。

  1. 前序遍历——访问根节点的操作发生在遍历其左右子树之前(根 左 右)。
  2. 中序遍历——访问根节点的操作发生在遍历其左右子树之间(左 根 右)。
  3. 后序遍历——访问根节点的操作发生在遍历其左右子树之后(左 右 根)。
前序遍历
//前序遍历
void PreOrder(TreeNode* root)
{if (root == NULL){printf("n ");return;}printf("%d ", root->data);PreOrder(root->left);PreOrder(root->right);
}

中序遍历:

//中序遍历
void InOrder(TreeNode* root)
{if (root == NULL){printf("n ");return;}InOrder(root->left);printf("%d ", root->data);InOrder(root->right);
}

后序遍历:

//后序遍历
void PostOrder(TreeNode* root)
{if (root == NULL){printf("n ");return ;}PostOrder(root->left);PostOrder(root->right);printf("%d ", root->data);
}

3.1.2节点个数及高度

二叉树节点个数

//二叉树节点个数
int BinaryTreeSize(TreeNode* root)
{if (root == NULL){return 0;}return BinaryTreeSize(root->left) + BinaryTreeSize(root->right) + 1;//root == NULL ? 0 : BinaryTreeSize(root->left) + BinaryTreeSize(root->right) + 1;
}

二叉树叶子节点个数

//二叉树叶子节点个数
int BinaryTreeLeafSize(TreeNode* root)
{if (root == NULL){return 0;}if (root->left == NULL && root->right == NULL){return 1;}return BinaryTreeLeafSize(root->left) + BinaryTreeLeafSize(root->right);
}

二叉树的高度

//二叉树高度
int BinaryTreeHight(TreeNode* root)
{if (root == NULL){return 0;}int leftHight = BinaryTreeHight(root->left);int rightHight = BinaryTreeHight(root->right);return leftHight > rightHight ? leftHight + 1 : rightHight + 1;
}

查找二叉树值为x的节点

找到一个节点就返回,因为函数只有一个返回值。

TreeNode* BinaryTreeFind(TreeNode* root, TreeDataType x)//查找值为x的节点
{if (root == NULL)return NULL;if (root->data == x){return root;}//将左右子树查找的节点记录下来,找到就返回这个节点,如果不记录就不会返回TreeNode* ret1 = BinaryTreeFind(root->left, x);if (ret1){return ret1;}TreeNode* ret2 = BinaryTreeFind(root->right, x);if (ret2)return ret2;return NULL;
}

3.1.3二叉树的销毁

void DestoryTree(TreeNode* root)//销毁
{if (root == NULL){return;}DestoryTree(root->left);DestoryTree(root->right);free(root);
}

传的是一级指针,在函数调用完之后再置为空

3.1.4层序遍历

把根节点入队列,然后根节点出队列时,将左右子树入队列,当队列不为空,取队头元素并输出。

void LevelOrder(TreeNode* root)//层序遍历
{Queue pq;QInit(&pq);if (root)//根节点先进队列QPush(&pq, root);while (!QEmpty(&pq)){TreeNode* front = QueueFront(&pq);QPop(&pq);printf("%d ", front->data);//左右子树入队列if (front->left){QPush(&pq, front->left);}if (front->right){QPush(&pq, front->right);}}
}

3.1.5判断二叉树是否为完全二叉树

运用层序遍历,将空节点也进队列,当队头元素为空时跳出循环,判断此时队列中的元素节点是否为空,为空则为完全二叉树,不为空则不是完全二叉树

bool BinaryTreeComplete(TreeNode* root)
{Queue pq;QInit(&pq);//根节点入队列if (root)QPush(&pq, root);while (!QEmpty(&pq)){TreeNode* front = QueueFront(&pq);QPop(&pq);//当队头为空的时候跳出if (front == NULL){break;}QPush(&pq, front->left);QPush(&pq, front->right);}//如果为完全二叉树,此时队列里全为空,如果出现非空则不是while (!QEmpty(&pq)){TreeNode* front = QueueFront(&pq);QPop(&pq);if (front != NULL){QDestory(&pq);return false;}}QDestory(&pq);return true;
}

3.2二叉树的oj

1.单值二叉树:965. 单值二叉树 - 力扣(LeetCode)

思路:递归整棵树,判断根的值是否等于左右子树的值
bool isUnivalTree(struct TreeNode* root) 
{if(root == NULL)return true;if(root->left && root->left->val != root->val)return false;if(root->right && root->right->val != root->val)return false;return isUnivalTree(root->left) && isUnivalTree(root->right);
}

2.相同的树: 100. 相同的树 - 力扣(LeetCode)

思路:递归两颗树,如果节点不相同就返回false。
bool isSameTree(struct TreeNode* p, struct TreeNode* q) 
{if(p == NULL&&q == NULL)return true;if(p == NULL||q == NULL)return false;if(p->val != q->val)return false;return isSameTree(p->left,q->left)&&isSameTree(p->right,q->right);
}

3.对称二叉树:101. 对称二叉树 - 力扣(LeetCode)

思路:将左子树和右子树拆出来,然后比较左子树和右子树,左子树的左是否等于右子树的右,左子树的右是否等于右子树的左。
bool _isSymmetric(struct TreeNode* p,struct TreeNode* q)
{if(p == NULL && q == NULL) return true;if(p == NULL || q == NULL)return false;if(p->val != q->val)return false;return _isSymmetric(p->left,q->right) && _isSymmetric(p->right,q->left);
}bool isSymmetric(struct TreeNode* root) 
{if(root == NULL)return true;struct TreeNode* left = root->left;struct TreeNode* right = root->right;return _isSymmetric(left,right);
}

4.二叉树的遍历144. 二叉树的前序遍历 - 力扣(LeetCode)

int TreeSize(struct TreeNode*root)
{return root == NULL ? 0 : TreeSize(root->left) +TreeSize(root->right) + 1;
}void PreOrder(struct TreeNode* root,int* arr,int *i)
{if(root == NULL){return;}arr[(*i)++] = root->val;PreOrder(root->left,arr,i);PreOrder(root->right,arr,i);
}int* preorderTraversal(struct TreeNode* root, int* returnSize) 
{*returnSize = TreeSize(root);int *ret = (int*)malloc(sizeof(int)*(*returnSize));int i = 0;PreOrder(root, ret, &i);return ret;
}

思路:直接前序遍历,但数组++时应该传i的指针,如果不传指针,递归在创建函数栈帧时不会保留i的值。
5.另一颗树的子树: 572. 另一棵树的子树 - 力扣(LeetCode)
思路:先判断root是否为空,如果为空则为false,不为空就判断是否相同的树,再递归左子树右子树。
bool issameTree(struct TreeNode* q, struct TreeNode *p)
{if(q == NULL && p == NULL){return true;}if(q == NULL || p == NULL){return false;}if(q->val != p->val){return false;}return issameTree(q->left,p->left) && issameTree(q->right,p->right);
}bool isSubtree(struct TreeNode* root, struct TreeNode* subRoot) 
{if(root == NULL){return false;}if(issameTree(root,subRoot)){return true;}return isSubtree(root->left,subRoot)||isSubtree(root->right,subRoot);}

6.二叉树的遍历:二叉树遍历_牛客题霸_牛客网

思路:创建树,当树为‘#’的时候为空,创建树的节点,然后递归左子树右子树创建树
#include <stdio.h>
#include <stdlib.h>typedef struct TreeNode
{char val;struct TreeNode* left;struct TreeNode* right;
}TreeNode;TreeNode* CreatTree(char *arr,int *i)
{while(arr[*i] == '#'){(*i)++;return NULL;}TreeNode* root = (TreeNode*)malloc(sizeof(TreeNode));root->val = arr[(*i)++];root->left = CreatTree(arr, i);root->right = CreatTree(arr, i);return root;
}void InOrder(TreeNode* root)
{if(root == NULL){return;}InOrder(root->left);printf("%c ",root->val);InOrder(root->right);
}int main() 
{char arr[100];scanf("%s",arr);int i = 0;TreeNode* root = CreatTree(arr, &i);InOrder(root);return 0;
}

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

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

相关文章

linux驱动-输入子系统框架分析

接下来&#xff0c;来分析三个结构体 打开这个文件drivers\input\evdev.c 第一步&#xff1a;要找到它的入口函数evdev_init 看到了&#xff0c;入口的位置注册了一个 input_handler&#xff0c;并且对里面的值完成赋值&#xff0c;和之前学习&#xff0c;我自己注册platform驱…

【sqlmap使用】

sqlmap简介 sqlmap 目录结构 sqlmap常用参数 sqlmap实现注入 测试注入点&#xff0c;检测到注入点后&#xff0c;直接爆数据库名 python sqlmap.py –u http://172.16.12.2/7/9/strsql.php --data "usernameadmin" --dbs注意sqlmap在使用过程中可能会出现几个需要…

Redis为什么用跳表实现有序集合

Redis为什么用跳表实现有序集合 手写一个跳表 为了更好的回答上述问题以及更好的理解和掌握跳表&#xff0c;这里可以通过手写一个简单的跳表的形式来帮助读者理解跳表这个数据结构。 我们都知道有序链表在添加、查询、删除的平均时间复杂都都是 O(n) 即线性增长&#xff0c…

微服务核心——网关路由

目录 前言 一、登录存在的问题归纳 二、*微服务网关整体方案 三、认识微服务网关 四、网关鉴权实现 五、OpenFeign微服务间用户标识信息传递实现 六、微服务网关知识追问巩固 前言 本篇文章具体讲解微服务中网关的实现逻辑、用于解决什么样的问题。其中标题中标注* 涉…

消息中间件类型介绍

ActiveMQ&#xff1a; ActiveMQ可是个老将了&#xff0c;它功能全面、稳定可靠&#xff0c;还支持多种协议和编程语言。如果你需要一个兼容性好、易于集成的消息中间件&#xff0c;ActiveMQ可是个不错的选择。 RabbitMQ&#xff1a; RabbitMQ以其简单易用和高性能著称。它支持丰…

5G在汽车零部件行业的应用

5G技术在汽车零部件行业的应用正在不断深入&#xff0c;为行业的智能化、自动化和高效化转型提供了强大的技术支持。 1、5G技术特点与优势 5G技术具有高速度、低延迟、大连接和切片技术等特点与优势。这些特性为汽车零部件行业提供了稳定、可靠、高效的通信连接&#xff0c;使…

MySQL【二】

查询列 SELECT [ALL | DISTINCT ] * | 列名1[,……列名n] FROM 表名; 查询所有选课学生的学号&#xff0c;结果去除重复值 select distinct sno from sc; 选择行 查询满足条件的数据集 SELECT 字段列表 FROM 表名 WHERE 查询条件 查询不属于数学系或外国语系的学生全部信息 …

【LLM论文日更】LongReward:利用人工智能反馈改进长上下文大语言模型

论文&#xff1a;https://arxiv.org/pdf/2410.21252代码&#xff1a;https://github.com/THUDM/LongReward机构&#xff1a;清华大学 & 中科院 & 智谱领域&#xff1a;长上下文LLM发表&#xff1a;arxiv 研究背景 研究问题&#xff1a;这篇文章要解决的问题是如何在长…

Windows Terminal终端美化

Windows Terminal 1. 下载&#xff1a; 终端&#xff1a; 直接在微软的store中搜索 windows terminal &#xff0c;直接获取即可 美化用到的字体&#xff1a;https://www.nerdfonts.com/font-downloads 这里的随便一个都可以&#xff0c;下载解压后&#xff0c;选中所有ttf文…

Go语言基础语法

一、创建工程 说明&#xff1a; &#xff08;1&#xff09;go.mod文件是go项目依赖管理文件&#xff0c;相当于前端的package.json&#xff0c;也就是Java项目中的Maven的pom.xml。 二、打印数据到控制台 &#xff08;1&#xff09;引入fmt &#xff08;2&#xff09;使用fmt…

【数据结构】二叉树——层序遍历

层序遍历 一、层序遍历二、层序遍历&#xff08;递归&#xff09;三、层序遍历&#xff08;非递归&#xff09;四、总结 一、层序遍历 层序遍历是一种广度优先遍历 以图上二叉树为例&#xff0c;层序遍历就是按照二叉树的深度一层一层进行遍历 遍历顺序&#xff1a; A B C D …

使用DJL和PaddlePaddle的口罩检测详细指南

使用DJL和PaddlePaddle的口罩检测详细指南 完整代码 该项目利用DJL和PaddlePaddle的预训练模型&#xff0c;构建了一个口罩检测应用程序。该应用能够在图片中检测人脸&#xff0c;并将每张人脸分类为“戴口罩”或“未戴口罩”。我们将深入分析代码的每个部分&#xff0c;以便…

Pandas 数据清洗

1.数据清洗定义 数据清洗是对一些没有用的数据进行处理的过程。很多数据集存在数据缺失、数据格式错误、错误数据或重复数据的情况&#xff0c;如果要使数据分析更加准确&#xff0c;就需要对这些没有用的数据进行处理。 2.清洗空值 DataFrame.dropna(axis0, howany, threshN…

【GL08】STM32--ADC/DAC

一、ADC简介 ADC 即模拟信号到数字信号的转换&#xff0c;即用数字信号展现模拟的世界&#xff0c;所有的计算机或者数字处理器只能接受以 0 和 1 两种状态的数字信号&#xff0c;而对于模拟信号&#xff0c;则无法识别&#xff0c;而需要经过模拟数字转换器来感受模拟的世界。…

Blender进阶:着色器节点

11 着色器节点 11.1着色器 着色器Shader&#xff0c;负责给物体表面着色。 综合以下参数&#xff1a; -基础色-金属度、粗超度、透明度-法向-入射光颜色、强度、角度。。 着色器本质上是一段程序、算法&#xff0c;即着色器编程。 在节点编辑器中&#xff0c;支持算法的可…

SQLark百灵连接——整合项目监控过程

关键词&#xff1a;SQL编写、数据查询、数据导入、达梦数据库、项目管理、信息透明 项目监控背景 作为新手项目经理的我&#xff0c;经常觉得哪儿哪儿都是问题&#xff0c;今天催这个&#xff0c;明天推那个&#xff0c;可就是什么事都推不动&#xff0c;谁都不配合。后来&…

ELK配置转存redis缓存,采集nginx访问日志

在136服务器上部署mysql 启动mysql服务 可通过以下命令查找安装的软件包 怎么查找安装软件的日志文件位置rpm -qc mysql-server&#xff0c;即可显示mysql.log位置 也可通过查找配置文件中的log关键字来查找log文件日志位置 用awk命令&#xff0c;以切割&#xff0c;输出第二个…

提升当当网数据爬取效率:代理IP并发抓取技术

在当今的互联网时代&#xff0c;数据已成为企业竞争的关键资源。爬虫技术作为获取网络数据的重要手段&#xff0c;其应用范围越来越广泛。然而&#xff0c;随着各大网站反爬虫机制的不断加强&#xff0c;爬虫面临着越来越多的挑战。其中&#xff0c;IP被封禁是最常见的问题之一…

基于微信小程序的图书馆座位预约系统+LW示例参考

系列文章目录 1.基于SSM的洗衣房管理系统原生微信小程序LW参考示例 2.基于SpringBoot的宠物摄影网站管理系统LW参考示例 3.基于SpringBootVue的企业人事管理系统LW参考示例 4.基于SSM的高校实验室管理系统LW参考示例 5.基于SpringBoot的二手数码回收系统原生微信小程序LW参考示…

学习笔记:ElasticSearch搜索引擎

学习视频&#xff1a;【尚硅谷】ElasticSearch教程入门到精通&#xff08;基于ELK技术栈elasticsearch 7.x8.x新特性&#xff09; 学习笔记&#xff1a;Elasticsearch学习笔记 目录 第1章 Elasticsearch概述01. 开篇02. 技术选型 2. 第二章 ElasticSearch入门03. 环境准备04. …