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

C语言:二叉树的构建

目录

一、二叉树的存储

1.1        顺序存储

1.2        链式存储

二、二叉树的顺序结构及实现

2.1堆的概念及结构

2.2堆的构建

2.3堆的插入

2.4堆顶的删除

2.5堆的完整代码

三、二叉树的链式结构及实现

3.1链式二叉树的构建

3.2链式二叉树的遍历

3.2.1前序遍历

3.2.2中序遍历

3.2.3后序遍历

3.2.4层序遍历


一、二叉树的存储

二叉树一般用顺序结构存储或链式结构存储。

1.1        顺序存储

顺序存储就是用数组来存储,但一般使用数组只适合用来表示完全二叉树,如果不是完全二叉树,就可能存在空间浪费,甚至极大的空间浪费。二叉树的顺序存储在物理结构上是数组,在逻辑上是一颗二叉树。

例:1、完全二叉树

2、非完全二叉树

由上面两幅图可以看出,如果二叉树是非完全二叉树,则在数组中会存在很多空位,导致空间浪费。

1.2        链式存储

链式存储就是用链表来表示二叉树,一般用结构体表示每一个节点,每个节点中有三个域,数据域和左右指针域。数据域用来存储节点的数据,左指针指向左孩子,右指针指向右孩子。

二、二叉树的顺序结构及实现

在现实中,一般的二叉树用顺序存储可能会存在大量空间浪费,所以一般只用堆来用顺序结构存储。

这里的堆与地址空间中的堆不同,前者是数据结构,后者是操作系统中的一块内存区域分段。

2.1堆的概念及结构

1.概念:如果有一个集合K,将它的所有元素按照完全二叉树的顺序存储方式存储在一个一维数组中,并满足K(i)<=K(2*i+1)且K(i)<=K(2*i+1),则称为小堆,如果大于等于就是大堆。将根节点最大的堆叫做最大堆或大根堆,根节点最小的堆叫做最小堆或小根堆。

2.性质:

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

堆总是一颗完全二叉树。

 

2.2堆的构建

void HeapCreate(Heap* hp, HPDataType* a, int n)
{assert(hp);//断言堆是否存在hp->_a = NULL;//将数据置为空hp->_capacity = 0;//将堆的容量清零hp->_size = 0;//将堆的大小清零
}

2.3堆的插入

void AdjustUp(HPDataType* a, int child)//向上调整堆
{int parent = (child - 1) / 2;//父节点在孩子节点-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)
{assert(hp);//断言堆是否存在if (hp->_size == hp->_capacity)//如果堆的大小等于容量,需扩容{size_t newcapacity = hp->_capacity == 0 ? 4 : hp->_capacity * 2;HPDataType* tmp = realloc(hp->_a, sizeof(HPDataType) * newcapacity);//定义临时变量扩容if (tmp == NULL)//判断扩容是否成功{perror("realloc fail");//扩容失败return;}hp->_a = tmp;//将变量传给ahp->_capacity = newcapacity;//扩容}hp->_a[hp->_size] = x;//将值插入堆的最后hp->_size++;//堆的大小加1AdjustUp(hp->_a ,hp->_size -1);//用向上调整的方法重新调整堆,防止插入后不再是大堆或小堆
}

2.4堆顶的删除

void AdjustUp(HPDataType* a, int child)//向下调整堆
{int parent = (child - 1) / 2;//父节点在孩子节点-1除2的位置while (child>0)//如果孩子节点的位置不在最上面{if (a[child] < a[parent])//如果父节点小于孩子节点{swap(&a[child], &a[parent]);//交换值child = parent;parent = (child - 1) / 2;}else{break;}}
}
// 堆的删除
void HeapPop(Heap* hp)
{assert(hp);//断言堆是否存在assert(hp->_size > 0);//断言堆的大小是否为0swap(&hp->_a[0], &hp->_a[hp->_size - 1]);//交换堆顶和堆尾的值hp->_size--;//堆的大小减1AdjustDown(hp->_a, hp->_size, 0);//向下调整堆
}

2.5堆的完整代码


// 堆的构建
void HeapCreate(Heap* hp, HPDataType* a, int n)
{assert(hp);//断言堆是否存在hp->_a = NULL;//将数据置为空hp->_capacity = 0;//将堆的容量清零hp->_size = 0;//将堆的大小清零
}// 堆的销毁
void HeapDestory(Heap* hp)
{assert(hp);//断言堆是否存在free(hp->_a);//释放数据hp->_a = NULL;//将指针置为空hp->_capacity = 0;将堆的容量清零hp->_size = 0;//将堆的大小清零
}
void swap(HPDataType* x, HPDataType* y)
{HPDataType tmp = *x;*x = *y;*y = tmp;
}void AdjustDown(HPDataType* a, int n, int parent)
{int child = parent * 2 + 1;//左孩子节点是父亲节点的2倍加1while (child < n)//如果孩子节点不在最后{//找到左右孩子中较小的if (child + 1 < n && a[child + 1] < a[child])//如果左孩子大于右孩子{++child;}if (a[child] < a[parent])//如果孩子小于父亲{swap(&a[child], &a[parent]);//交换父节点与子节点parent = child;child = parent * 2 + 1;}else{break;}}
}void AdjustUp(HPDataType* a, int child)//向上调整堆
{int parent = (child - 1) / 2;//父节点在孩子节点-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)
{assert(hp);//断言堆是否存在if (hp->_size == hp->_capacity)//如果堆的大小等于容量,需扩容{size_t newcapacity = hp->_capacity == 0 ? 4 : hp->_capacity * 2;HPDataType* tmp = realloc(hp->_a, sizeof(HPDataType) * newcapacity);//定义临时变量扩容if (tmp == NULL)//判断扩容是否成功{perror("realloc fail");//扩容失败return;}hp->_a = tmp;//将变量传给ahp->_capacity = newcapacity;//扩容}hp->_a[hp->_size] = x;//将值插入堆的最后hp->_size++;//堆的大小加1AdjustUp(hp->_a ,hp->_size -1);//用向上调整的方法重新调整堆,防止插入后不再是大堆或小堆
}// 取堆顶的数据
HPDataType HeapTop(Heap* hp)
{assert(hp);//断言堆是否存在return hp->_a[0];
}// 堆的删除
void HeapPop(Heap* hp)
{assert(hp);//断言堆是否存在assert(hp->_size > 0);//断言堆的大小是否为0swap(&hp->_a[0], &hp->_a[hp->_size - 1]);//交换堆顶和堆尾的值hp->_size--;//堆的大小减1AdjustDown(hp->_a, hp->_size, 0);//向下调整堆
}// 堆的数据个数
int HeapSize(Heap* hp)
{assert(hp);return hp->_size;
}
// 堆的判空
int HeapEmpty(Heap* hp)
{assert(hp);return hp->_size == 0;
}// 对数组进行堆排序
void HeapSort(int* a, int n)
{for (int i = (n - 1) / 2; i >= 0; --i){AdjustDown(a, n, i);}
}

三、二叉树的链式结构及实现

一颗链式二叉树一般用结构体表示,结构体中一个存储数据,一个链表指向左孩子节点,一个指向右孩子节点。

typedef int BTDataType;//方便后面改变二叉树中的数据类型typedef struct BinaryTreeNode
{BTDataType data;//二叉树存储数据的节点struct BinaryTreeNode* left;//左孩子节点struct BinaryTreeNode* right;//右孩子节点
}BTNode;//重命名

3.1链式二叉树的构建

BTNode* BinaryTreeCreate(BTDataType* a, int n, int* pi)//二叉树一般需要手动扩建
{BTNode* n1 = BuyNode('A');BTNode* n2 = BuyNode('B');BTNode* n3 = BuyNode('C');BTNode* n4 = BuyNode('D');BTNode* n5 = BuyNode('E');BTNode* n6 = BuyNode('F');BTNode* n7 = BuyNode('G');BTNode* n8 = BuyNode('H');n1->left = n2;n1->right = n3;n2->left = n4;n2->right = n5;n3->left = n6;n3->right = n7;n5->left = n8;return n1;
}

3.2链式二叉树的遍历

二叉树的遍历就是按照某种特殊规则,依次对二叉树的节点进行操作,每个节点只能操作一次。

二叉树的遍历一般有4种方式。

3.2.1前序遍历

前序遍历:优先操作每个节点的自身,后操作左节点,最后操作右节点。

例如上图的树就是按照A-B-D-E-H-C-F-G的顺序操作。

从A开始,先操作A的自身,再访问A的左节点B。

B节点先操作自身,再访问B的左节点D。

D节点操作自身,无孩子节点则返回到B,访问B的右节点E。 

E节点操作自身,再访问E的左节点H。

H节点操作自身,无孩子节点则返回到E,E无左孩子节点则返回到B,B的左右孩子都已访问则返回到A,访问A的右节点C。

C节点操作自身,再访问C的左节点F。

F节点操作自身,无孩子节点则返回C,访问C的右节点G

G节点操作自身,无孩子节点,访问结束。

// 二叉树前序遍历 
void BinaryTreePrevOrder(BTNode* root) 
{if (root == NULL){printf("N ");//如果节点为空打印Nreturn;}printf("%c ", root->data);//打印节点BinaryTreePrevOrder(root->left);//访问左节点BinaryTreePrevOrder(root->right);//访问右节点
}

3.2.2中序遍历

中序遍历:优先操作每个节点的左节点,后操作自身,最后操作右节点。

上图按照D-B-H-E-A-F-C-G的顺序操作。 

从A开始,先访问A的左节点B,B节点先访问D,D无左节点,操作自身。

D无右节点,则返回B,操作B的自身,再访问B的右节点E。

E节点先访问左节点H,H无左节点,操作自身,H无右节点,则返回E节点。

E节点操作自身,无右节点,返回B节点,再返回A节点。

A节点操作自身,再访问右节点C,C节点访问左节点F。

F无左节点操作自身,无右节点,返回C节点。

C节点操作自身,再访问C的右节点G。

G无左节点,操作自身,无右节点,访问结束。

// 二叉树中序遍历
void BinaryTreeInOrder(BTNode* root)
{if (root == NULL){printf("N ");//如果节点为空打印Nreturn;}BinaryTreePrevOrder(root->left);//访问左节点printf("%c ", root->data);//打印节点BinaryTreePrevOrder(root->right);//访问右节点
}

3.2.3后序遍历

后序遍历:优先操作每个节点的左节点,后操作右节点,最后操作自身。

上图按照D-B-H-E-F-C-G-A的顺序操作。

从A开始,访问A的左节点B,再访问B的左节点D,D无左右节点,操作自身,返回B节点。

访问B节点的右节点E,再访问E的左节点H,H无左右节点, 操作自身,返回E节点。

E节点操作自身,返回B节点。

B节点操作自身,返回A节点,再访问A节点的右节点C,访问C的左节点F。

F无左右节点,操作自身,返回C节点,访问C节点的右节点G。

G无左右节点,操作自身,返回C节点。

C节点操作自身,返回A节点。

A节点操作自身,访问结束。

// 二叉树后序遍历
void BinaryTreePostOrder(BTNode* root)
{if (root == NULL){printf("N ");//如果节点为空打印Nreturn;}BinaryTreePrevOrder(root->left);//访问左节点BinaryTreePrevOrder(root->right);//访问右节点printf("%c ", root->data);//打印节点
}

3.2.4层序遍历

 层序遍历:按照二叉树的每一层,一层一层的从左向右操作。

实现二叉树的层序遍历需要用到队列的知识。

队列是一个有着先进先出原则的链表,先进的元素永远比后进的元素先出来。通过队列的规则,只要二叉树的每一个节点出队列时将其左右孩子节点入队列即可完成二叉树的层序遍历。

上图的操作顺序是A-B-C-D-E-F-G-H

A节点入队列,A节点出队列,将A的左右子节点BC入队列。

此时队列中有B-C,将B出队列,B的左右子节点DE入队列。

此时队列中有C-D-E,将C出队列,C的左右子节点FG入队列。

此时队列中有D-E-F-G,将D出队列,D无子节点。

此时队列中有E-F-G,将F出队列,F的左节点H入队列。

此时队列中有F-G-H,均无子节点,一个一个出队列即可。

 队列头文件代码

#pragma once
#include<stdio.h>
#include<stdbool.h>
#include<assert.h>
#include<string.h>
#include<stdlib.h>
typedef  struct BinTreeNode* QDataType;
// 链式结构:表示队列 
typedef struct QueueNode
{QDataType data;struct QueueNode* next;
}QNode;
// 队列的结构 
typedef struct Queue
{QNode* phead;QNode* ptail;int size;
}Queue;
// 初始化队列 
void QueueInit(Queue* q);
// 队尾入队列 
void QueuePush(Queue* q, QDataType data);
// 队头出队列 
void QueuePop(Queue* q);
// 获取队列头部元素 
QDataType QueueFront(Queue* q);
// 获取队列队尾元素 
QDataType QueueBack(Queue* q);
// 获取队列中有效元素个数 
int QueueSize(Queue* q);
// 检测队列是否为空,如果为空返回非零结果,如果非空返回0 
int QueueEmpty(Queue* q);
// 销毁队列 
void QueueDestroy(Queue* q);

队列代码

#include"1.h"// 初始化队列 
void QueueInit(Queue* q)
{assert(q);//断言队列是否存在q->phead = NULL;//将头节点的置为空q->ptail = NULL;//将尾节点置为空q->size = 0;//将队列大小初始化为0
}// 队尾入队列 
void QueuePush(Queue* pq, QDataType x)
{assert(pq);//断言队列是否存在QNode* newnode = (QNode*)malloc(sizeof(QNode));//创建临时变量if (newnode == NULL)//判断变量是否创建成功{perror("malloc fail");return;}newnode->data = x;//将要入队列的值给临时变量newnode->next = NULL;//将临时变量的指向下一个节点的指针置空if (pq->ptail)//如果尾队列存在,则队列中含有数据{pq->ptail->next = newnode;//将原本尾队列指向下一个节点的指针指向临时变量pq->ptail = newnode;//将临时变量设为尾节点}else//尾队列不存在,则队列为空{pq->phead = pq->ptail = newnode;//将头节点和尾节点都设为临时变量}pq->size++;//队列大小加1
}// 队头出队列 
void QueuePop(Queue* q)
{assert(q);//断言队列是否存在assert(q->phead != NULL);//断言队列的头节点是否为空if (q->phead->next == NULL)//队列头节点的下一个节点为空,则队列中只有一个元素{free(q->phead);//释放头节点q->phead = q->ptail = NULL;//将头节点和尾节点置空}else//队列中不止1个元素{QNode* next = q->phead->next;//创建临时变量指向头节点的下一个节点free(q->phead);//是否头节点q->phead = next;//将头节点的下一个节点设为头节点}q->size--;//队列大小减1
}// 获取队列头部元素 
QDataType QueueFront(Queue* q)
{assert(q);//断言队列是否存在assert(q->phead != NULL);//断言队列的头节点是否为空return q->phead->data;//返回队列头节点的数据
}// 获取队列队尾元素 
QDataType QueueBack(Queue* q)
{assert(q);//断言队列是否存在assert(q->ptail != NULL);//断言队列的尾节点是否为空return q->ptail->data;//返回队列尾节点的数据
}// 获取队列中有效元素个数 
int QueueSize(Queue* q)
{assert(q);//断言队列是否存在return q->size;//返回队列的大小
}// 检测队列是否为空,如果为空返回非零结果,如果非空返回0 
int QueueEmpty(Queue* q)
{assert(q);//断言队列是否存在return q->size == 0;//判断队列的大小是否为0
}// 销毁队列 
void QueueDestroy(Queue* q)
{assert(q);//断言队列是否存在QNode* cur = q->phead;//定义临时节点等于头节点while (cur)//如果头节点不为空{QNode* next = cur->next;//定义临时节点指向头节点的下一个节点free(cur);//释放头节点cur = next;//将下一个节点当作头节点}q->phead = NULL;//将头节点指针置空q->ptail = NULL;//将尾节点指针置空q->size = 0;//将队列大小置为0
}

 二叉树头文件

#pragma once
#include<stdio.h>
#include<string.h>
#include<assert.h>
#include<stdlib.h>
typedef int BTDataType;//方便后面改变二叉树中的数据类型typedef struct BinaryTreeNode
{BTDataType data;//二叉树存储数据的节点struct BinaryTreeNode* left;//左孩子节点struct BinaryTreeNode* right;//右孩子节点
}BTNode;//重命名#include"1.h"// 通过前序遍历的数组"ABD##E#H##CF##G##"构建 二叉树
BTNode* BinaryTreeCreate(BTDataType* a, int n, int* pi);
// 二叉树销毁
void BinaryTreeDestory(BTNode** root);
// 二叉树节点个数
int BinaryTreeSize(BTNode* root);
// 二叉树叶子节点个数
int BinaryTreeLeafSize(BTNode* root);
// 二叉树第k层节点个数
int BinaryTreeLevelKSize(BTNode* root, int k);
// 二叉树查找值为x的节点
BTNode* BinaryTreeFind(BTNode* root, BTDataType x);
// 二叉树前序遍历 
void BinaryTreePrevOrder(BTNode* root);
// 二叉树中序遍历
void BinaryTreeInOrder(BTNode* root);
// 二叉树后序遍历
void BinaryTreePostOrder(BTNode* root);
// 层序遍历
void BinaryTreeLevelOrder(BTNode* root);
// 判断二叉树是否是完全二叉树
int BinaryTreeComplete(BTNode* root);

二叉树代码

#include"tree.h"
BTNode* BuyNode(BTDataType a)//a是要创建的值
{BTNode* newnode = (BTNode*)malloc(sizeof(BTNode));//定义临时变量扩容if (newnode == NULL){printf("malloc fail");//扩容失败return NULL;}newnode->data = a;newnode->left = NULL;newnode->right = NULL;return newnode;
}
// 通过前序遍历的数组"ABD##E#H##CF##G##"构建二叉树
BTNode* BinaryTreeCreate(BTDataType* a, int n, int* pi)//二叉树一般需要手动扩建
{BTNode* n1 = BuyNode('A');BTNode* n2 = BuyNode('B');BTNode* n3 = BuyNode('C');BTNode* n4 = BuyNode('D');BTNode* n5 = BuyNode('E');BTNode* n6 = BuyNode('F');BTNode* n7 = BuyNode('G');BTNode* n8 = BuyNode('H');n1->left = n2;n1->right = n3;n2->left = n4;n2->right = n5;n3->left = n6;n3->right = n7;n5->left = n8;return n1;
}// 二叉树销毁
void BinaryTreeDestory(BTNode** root)
{assert(root);free(root);}// 二叉树节点个数
int BinaryTreeSize(BTNode* root)
{return root == NULL ? 0 :BinaryTreeSize(root->left) + BinaryTreeSize(root->right) + 1;
}// 二叉树叶子节点个数
int BinaryTreeLeafSize(BTNode* root)
{if (root == NULL){return 0;}if (root->left == NULL && root->right == NULL){return 1;}return BinaryTreeLeafSize(root->left) + BinaryTreeLeafSize(root->right);
}// 二叉树第k层节点个数
int BinaryTreeLevelKSize(BTNode* root, int k)
{assert(k > 0);if (root == NULL){return 0;}if (k == 1){return 1;}return BinaryTreeLevelKSize(root->left, k - 1) + BinaryTreeLevelKSize(root->right, k - 1);
}// 二叉树查找值为x的节点
BTNode* BinaryTreeFind(BTNode* root, BTDataType x)
{if (root == NULL){return NULL;}if (root->data == x){return root;}BTNode* ret1= BinaryTreeFind(root->right, x);if (ret1){return ret1;}BTNode* ret2=BinaryTreeFind(root->left , x);if (ret2){return ret2;}return NULL;
}// 二叉树前序遍历 
void BinaryTreePrevOrder(BTNode* root) 
{if (root == NULL){printf("N ");//如果节点为空打印Nreturn;}printf("%c ", root->data);//打印节点BinaryTreePrevOrder(root->left);//访问左节点BinaryTreePrevOrder(root->right);//访问右节点
}
// 二叉树中序遍历
void BinaryTreeInOrder(BTNode* root)
{if (root == NULL){printf("N ");//如果节点为空打印Nreturn;}BinaryTreePrevOrder(root->left);//访问左节点printf("%c ", root->data);//打印节点BinaryTreePrevOrder(root->right);//访问右节点
}
// 二叉树后序遍历
void BinaryTreePostOrder(BTNode* root)
{if (root == NULL){printf("N ");//如果节点为空打印Nreturn;}BinaryTreePrevOrder(root->left);//访问左节点BinaryTreePrevOrder(root->right);//访问右节点printf("%c ", root->data);//打印节点
}
// 层序遍历
void TreeLevelOrder(BTNode* root)
{Queue q;//定义临时节点QueueInit(&q);//创建临时节点if (root)//如果节点不为空{QueuePush(&q, root);//节点入队列}while (!QueueEmpty(&q))//如果队列不为空{BTNode* front = QueueFront(&q);//获取队头元素QueuePop(&q);//队头元素出队列if (front)//如果节点存在{printf("%d ", front->data);//打印节点数据// 带入下一层QueuePush(&q, front->left);//左孩子节点入队列QueuePush(&q, front->right);//右孩子节点入队列}else{printf("N ");//不存在打印N}}printf("\n");QueueDestroy(&q);//销毁临时节点,防止空间泄露
}

相关文章:

C语言:二叉树的构建

目录 一、二叉树的存储 1.1 顺序存储 1.2 链式存储 二、二叉树的顺序结构及实现 2.1堆的概念及结构 2.2堆的构建 2.3堆的插入 2.4堆顶的删除 2.5堆的完整代码 三、二叉树的链式结构及实现 3.1链式二叉树的构建 3.2链式二叉树的遍历 3.2.1前序遍历 …...

软件测试工程师面试汇总功能测试篇

Q:一、进行测试用例设计的时候用到的方法有哪些&#xff1f; A:最常使用的测试用例设计方法包括等价类划分法、边界值分析方法、场景法、错误推测法。其中&#xff0c;最容易 发现错误的是边界值法&#xff0c;使用最多的是场景法。以注册为例&#xff1a;首先从需求确定用户名…...

javaAPI1

API application pragramming interface 应用程序编程接口 除java.lang包以外,其他包中的类在使用时需要导入 建包 package com.abc.javabean; 导包格式,import 包名.类名 API使用技巧 1,先看关键字 2,看参数列表 3,看返回值类型 String 封装字符串和处理字符串的类…...

案例研究|DataEase实现物业数据可视化管理与决策支持

河北隆泰物业服务有限责任公司&#xff08;以下简称为“隆泰物业”&#xff09;创建于2002年&#xff0c;总部设在河北省高碑店市&#xff0c;具有国家一级物业管理企业资质&#xff0c;通过了质量体系、环境管理体系、职业健康安全管理体系等认证。自2016年至今&#xff0c;隆…...

Android Studio Iguana | 2023.2.1 补丁 1

Android Studio Iguana | 2023.2.1 Canary 3 已修复的问题Android Gradle 插件 问题 295205663 将 AGP 从 8.0.2 更新到 8.1.0 后&#xff0c;任务“:app:mergeReleaseClasses”执行失败 问题 298008231 [Gradle 8.4][升级] 由于使用 kotlin gradle 插件中已废弃的功能&#…...

iOS17 隐私协议适配详解

1. 背景 网上搜了很多文章&#xff0c;总算有点头绪了。其实隐私清单最后做出来就是一个plist文件。找了几个常用三方已经配好的看了看&#xff0c;比着做就好了。 WWDC23 中关于隐私部分的更新&#xff08;WWDC23 隐私更新官网&#xff09;&#xff0c;其中提到了第三方 SDK 的…...

LeetCode 每日一题 Day 116-122

2580. 统计将重叠区间合并成组的方案数 给你一个二维整数数组 ranges &#xff0c;其中 ranges[i] [starti, endi] 表示 starti 到 endi 之间&#xff08;包括二者&#xff09;的所有整数都包含在第 i 个区间中。 你需要将 ranges 分成 两个 组&#xff08;可以为空&#xf…...

linux离线安装jenkins及使用教程

本教程采用jenkins.war的方式离线安装部署&#xff0c;在线下载的方式会遇到诸多问题&#xff0c;不宜采用 基本环境&#xff1a; 1.jdk环境&#xff0c;Jenkins是java语言开发的&#xff0c;因需要jdk环境。 2.git/svn客户端&#xff0c;因一般代码是放在git/svn服务器上的&a…...

NXP-S32DS软件安装

文章目录 一、安装包获取二、S32DS安装三、芯片插件安装 一、安装包获取 登录NXP官网&#xff0c;进入软件目录https://www.nxp.com/ 下载S32DS软件和RTD驱动库&#xff0c;并安装S32DS软件。 单击“S32DS.3.5_b220726_win32.x86_64.exe”下载该软件 点击“License Keys”&…...

26版SPSS操作教程(初级第十五章)

前言 #由于导师最近布置了学习SPSS这款软件的任务&#xff0c;因此想来平台和大家一起交流下学习经验&#xff0c;这期推送内容接上一次第十四章的学习笔记&#xff0c;希望能得到一些指正和帮助~ 粉丝及官方意见说明 #针对官方爸爸的意见说的推送缺乏操作过程的数据案例文件…...

docker部署实用的运维开发手册

下载镜像 docker pull registry.cn-beijing.aliyuncs.com/wuxingge123/reference:latestdocker-compose部署 vim docker-compose.yml version: 3 services:reference:container_name: referenceimage: registry.cn-beijing.aliyuncs.com/wuxingge123/reference:latestports:…...

Oracle VM(虚拟机)性能监控工具

Oracle VM是一个独立的虚拟化环境&#xff0c;由 Oracle 提供支持和设计&#xff0c;旨在为运行虚拟机提供轻量级、安全的基于服务器的平台。Oracle VM 能够在受支持的虚拟化环境中部署操作系统和应用软件&#xff0c;Oracle VM 将用户和管理员与底层虚拟化技术隔离开来&#x…...

1.8 python 模块 time、random、string、hashlib、os、re、json

ython之模块 一、模块的介绍 &#xff08;1&#xff09;python模块&#xff0c;是一个python文件&#xff0c;以一个.py文件&#xff0c;包含了python对象定义和pyhton语句 &#xff08;2&#xff09;python对象定义和python语句 &#xff08;3&#xff09;模块让你能够有逻辑地…...

iOS苹果签名共享签名是什么以及如何获取?

哈喽&#xff0c;大家好呀&#xff0c;咕噜淼淼又来和大家见面啦&#xff0c;最近有很多朋友都来向我咨询共享签名iOS苹果IPA共享签名是什么&#xff0c;针对这个问题&#xff0c;淼淼来解答一下大家的疑惑并告诉大家iOS苹果ipa共享签名需要如何获取。 现在苹果签名在市场上的…...

python爬虫下载音乐

本文使用创作助手。 你可以使用Python的requests库来实现爬虫下载音乐。以下是一个简单的示例代码&#xff1a; import requestsdef download_music(url, file_path):response requests.get(url)with open(file_path, wb) as file:file.write(response.content)print(f"…...

HarmonyOS实战开发-一次开发,多端部署-视频应用

介绍 随着智能设备类型的不断丰富&#xff0c;用户可以在不同的设备上享受同样的服务&#xff0c;但由于设备形态不尽相同&#xff0c;开发者往往需要针对具体设备修改或重构代码&#xff0c;以实现功能完整性和界面美观性的统一。OpenHarmony为开发者提供了“一次开发&#x…...

关于v114之后的chromedriver及存放路径

使用selenium调用浏览器时&#xff0c;我一直调用谷歌浏览器&#xff0c;可浏览器升级后&#xff0c;就会再次遇到以前遇到过的各种问题&#xff0c;诸如&#xff1a;1、怎么关闭浏览器更新&#xff1b;2、去哪儿下载chromedriver&#xff1b;3、114版本之后的驱动去哪儿下载&a…...

http模块 服务器端如何响应(获取)静态资源?

一、静态资源与动态资源介绍&#xff1a; &#xff08;1&#xff09;静态资源 内容长时间不改变的资源。eg&#xff1a;图片、视频、css js html文件、字体文件... &#xff08;2&#xff09;动态资源 内容经常更新的资源。eg&#xff1a;百度首页、淘宝搜索列表... 二、服…...

基于PHP的校园招聘管理系统

有需要请加文章底部Q哦 可远程调试 基于PHP的校园招聘管理系统 一 介绍 此校园招聘管理系统基于原生PHP开发&#xff0c;数据库mysql&#xff0c;前端bootstrap。系统角色分为个人用户&#xff0c;企业和管理员三种。 技术栈&#xff1a;phpmysqlbootstrapphpstudyvscode 二…...

LLMs 可能在 2 年内彻底改变金融行业

在艾伦图灵研究所&#xff08;The Alan Turing Institute&#xff09;最新的一项研究中&#xff0c;我们看到了大型语言模型&#xff08;Large Language Models&#xff0c;LLMs&#xff09;的一种可能性。它有望通过检测欺诈行为、生成财务洞察以及自动化客户服务&#xff0c;…...

nodejs 中 yarn的安装和使用

Yarn是一个快速、可靠、易于使用的包管理工具,它是Facebook、Google、Tencent等公司使用的默认JavaScript包管理工具。Yarn可以帮助开发者在项目中管理依赖,确保不同环境之间的依赖一致性,并且加速依赖的下载和安装。 安装Yarn Yarn支持多种操作系统,包括macOS、Linux和W…...

软件工程学习笔记14——案例解析篇

案例解析篇 一、大型开源项目对软件工程的应用1、开发迭代过程 二、大厂是怎样应用软件工程的1、软件项目开发团队组成&#xff08;1&#xff09;软件开发团队规模小&#xff08;2&#xff09;没有专职测试&#xff08;3&#xff09;DevOps 文化 2、开发工具的使用3、项目开发流…...

【文件操作API的使用】

1.概念 这对聪明的你们来说简直就是&#xff0c;对吗。 那什么是文件操作符&#xff0c;文件操作又有哪些步骤呢&#xff1f; 文件操作符通常用于指代在计算机编程中用于处理文件的特殊符号或标识符。在很多编程语言中&#xff0c;文件操作符被用于打开、关闭、读取和写入文件…...

C++ 让类只在堆或栈上分配

1. 让类只在栈上或堆上分配内存 在C中&#xff0c;类的对象建立分为两种&#xff1a; 一种是静态建立&#xff0c;如A a&#xff1b; 另一种是动态建立&#xff0c;如A* ptrnew A&#xff1b;这两种方式是有区别的。 1、静态建立类对象&#xff1a;是由编译器为对象在栈空间…...

SpringMVC源码分析(九)--返回值解析器

1.返回值解析器介绍 返回值解析器用于解析Hanlder执行方法后的返回结果,例如将方法上标注有@ResponseBody注解的返回值解析成JSON、将方法返回的字符串作为视图名等 SpringMVC中默认的返回值解析器见RequestMappingHandlerAdapter#getDefaultReturnValueHandlers private L…...

京西商城——创建订单和获取订单接口

在之前的写过的接口中&#xff0c;我先后用了基于View和APIView来编写视图类 基于APIView类的时候相对于View会有很多便捷&#xff0c;但其实drf还在APIView的基础上又封装了一个 GenericAPIView 类&#xff0c;会大大减少了在编写视图时的重复代码和在修改代码时的工作量。 G…...

大话设计模式之模板方法模式

模板方法模式&#xff08;Template Method Pattern&#xff09;是一种行为设计模式&#xff0c;它定义了一个算法的框架&#xff0c;将特定步骤的实现延迟到子类中。模板方法模式通过在父类中定义算法的骨架&#xff0c;而将具体步骤的实现留给子类来完成&#xff0c;从而使子类…...

新model开发记录

模型使用 -- 用blender导出为 fbx &#xff0c;修改渲染方式&#xff08;点击模型->Materials->Extract Materials(将材质从fbx中 单独提取出来了)->Materials 选择 Shader -> SimpleURPToonLitExample 点开脸的材质&#xff0c;勾选第一条&#xff09; 解决角色…...

ARMday1

1.总结keil5下载代码和编译代码需要注意的事项 答&#xff1a;下载代码时&#xff0c;确保stlink的驱动有效、魔术棒中硬件型号的连接 编译代码时&#xff0c;先将配置魔术棒里Debug中的Setting&#xff0c;将Flash中Reset and Run勾选上&#xff0c;并去除pack中的Enab…...

【C++风云录】创造视觉奇迹:探索C++图形编程的魅力与可能性

图形与界面&#xff1a;从SFML到Allegro&#xff0c;探索C图形编程的世界 前言 随着计算机图形技术和界面设计的快速发展&#xff0c;图形编程在软件开发中变得越来越重要。C作为一种功能强大的编程语言&#xff0c;为开发人员提供了丰富的图形编程工具和库。本文将介绍几个流…...

高端开发网站系统/推广代理

“综合交通出行大数据开放云平台是交通运输行业目前唯一实现开放共享的平台。”交通运输部公路科学研究院副院长岑晏青11日在2017年中国互联网&#xff0b;交通运输行业融合创业大赛创业分享会上说。 岑晏青介绍&#xff0c;截至目前&#xff0c;综合交通出行大数据开放云平台有…...

西安建网站价格低/网络营销服务的内容

这里的移位寄存器不是简单的向左移位将串行输入转换为并行输出&#xff0c;而且要保留最后一个周期的输入数作为下一次输出的最高位&#xff0c;代码如下所示&#xff1a; module shift_reg(clk,rst,din,dout//,ordy);input clk;input rst;input [7:0] din;output [31:0] dout…...

免费视频网站素材/宁波网络推广

1. The getter xxx was called on null. String判断空值时&#xff0c;null写在前面。 好吧&#xff0c;如果写过Android的同学应该是没问题&#xff0c;但是作为C#的童鞋来讲&#xff0c;真的是不知道 如&#xff1a; var image"12345";if(null ! image && …...

撰写网站规划书/百度客户端电脑版下载

为了减少c文件的编译依赖&#xff0c;前置声明经常使用&#xff0c;特别是在头文件中&#xff0c;如果不是必要&#xff0c;对于class基本都使用前置声明&#xff0c;而不是直接#include。 今天遇到一个问题&#xff0c;需要在某类的头文件里面引用到另外一个“类”&#xff0…...

自己电脑上做的网站 怎么让别人看/杭州网站建设公司

将下面的程序补充完整&#xff08;包括定义函数&#xff09;&#xff0c;使其能够完成图示的功能。请使用已有程序的风格。/* * Copyright (c) 2014,烟台大学计算机学院 * All right reserved. * 作者&#xff1a;邵帅 * 文件&#xff1a;demo.cpp * 完成时间&#xff1a;2014年…...

网上做问卷报酬不错的网站是/网络广告人社区

最近做了一个webservice应用,发现传输过程中,只要有特殊这符,就会导致出错 于是上网搜了一些方法,先把源WebService输出的内容进行特殊字符转换十六进制,接到收后再进行返转换 ///<summary>///StringExtenstion 的摘要说明///</summary>public static class String…...