數據結構~~鏈式二叉樹

目錄

一、基本概念

鏈式存儲概念

?二、鏈式二叉樹的結構

鏈式二叉樹結構

構建鏈式二叉樹

二叉樹的遍歷

?二叉樹節點和高度等

?二叉樹銷毀

三、鏈式二叉樹的練習

相同的樹?

對稱二叉樹

?另外一顆子樹

二叉樹前序遍歷?

?二叉樹遍歷

四、完整代碼

Tree.h

Tree.c

五、總結


一、基本概念

鏈式二叉樹是一種常見的數據結構,它是用鏈表結點來存儲二叉樹中的每一個結點,結點結構通常包括數據域和若干個指針域。其中,指針域用于指向左孩子結點和右孩子結點。

對于那些非完全二叉樹,由于順序存儲結構的空間利用率低,因此二叉樹一般都采用鏈式存儲結構。在鏈式二叉樹中,根據指針的數量可以分為二叉鏈和三叉鏈兩種結構。二叉鏈的結點包含存儲數據的變量、存儲左孩子的指針以及存儲右孩子的指針;而三叉鏈的結點除了包含存儲數據的變量、存儲左孩子的指針以及存儲右孩子的指針,還包含存儲雙親的指針。

二叉樹的遍歷是指按某條搜索路徑訪問樹中每個結點,使得每個結點均被訪問一次,而且僅被訪問一次。根據訪問根結點的順序不同可以分為前序遍歷、中序遍歷和后序遍歷。

鏈式存儲概念

鏈式存儲二叉樹的鏈式存儲結構是指,用鏈表來表示一棵二叉樹,即用鏈來指示元素的邏輯關系。 通常的方法是 鏈表中每個結點由三個域組成,數據域和左右指針域,左右指針分別用來給出該結點左孩子和右孩子所 在的鏈結點的存儲地址 。鏈式結構又分為二叉鏈和三叉鏈,當前我們學習中一般都是二叉鏈。

?二、鏈式二叉樹的結構

鏈式二叉樹結構

typedef int BTDataType;
typedef struct BinaryTreeNode
{BTDataType _data;struct BinaryTreeNode* _left;struct BinaryTreeNode* _right;
}BTNode;

構建鏈式二叉樹

int類型? 手撕構建方便前期調試

BTNode* BuyNode(BTDataType x)
{BTNode* newnode = (BTNode*)malloc(sizeof(BTNode));if (newnode == NULL){perror("malloc err");return NULL;}newnode->_data = x;newnode->_left = NULL;newnode->_right = NULL;return newnode;
}//123nn4n5nn67nn8nn  通過前序遍歷構建
BTNode* BinaryTreeCreate()
{BTNode* node1 = BuyNode(1);BTNode* node2 = BuyNode(2);BTNode* node3 = BuyNode(3);BTNode* node4 = BuyNode(4);BTNode* node5 = BuyNode(5);BTNode* node6 = BuyNode(6);BTNode* node7 = BuyNode(7);BTNode* node8 = BuyNode(8);node1->_left = node2;node1->_right = node6;node2->_left = node3;node2->_right = node4;node4->_right = node5;node6->_left = node7;node6->_right = node8;return node1;
}

char數組類型

// 通過前序遍歷的數組"ABD##E#H##CF##G##"構建二叉樹
BTNode* BinaryTreeCreateChar(BTDataType* a, int* pi)
{if (a[(*pi)] == '#'){(*pi)++;return NULL;}BTNode* newnode = (BTNode*)malloc(sizeof(BTNode));if (newnode == NULL){perror("malloc err");return NULL;}newnode->_data = a[(*pi)++];newnode->_left = BinaryTreeCreateChar(a, pi);newnode->_right = BinaryTreeCreateChar(a, pi);return newnode;
}

二叉樹的遍歷

前序:前序遍歷(Preorder Traversal 亦稱先序遍歷)——訪問根結點的操作發生在遍歷其左右子樹之前。

前序遍歷遞歸圖解:

// 二叉樹前序遍歷
void BinaryTreePrevOrder(BTNode* root)
{if (root == NULL){printf("NULL ");return;}printf("%d ", root->_data);BinaryTreePrevOrder(root->_left);BinaryTreePrevOrder(root->_right);
}

中序:中序遍歷(Inorder Traversal)——訪問根結點的操作發生在遍歷其左右子樹之中(間)

// 二叉樹中序遍歷
void BinaryTreeInOrder(BTNode* root)
{if (root == NULL){printf("NULL ");return;}BinaryTreeInOrder(root->_left);printf("%d ",root->_data);BinaryTreeInOrder(root->_right);
}

后序:后序遍歷(Postorder Traversal)——訪問根結點的操作發生在遍歷其左右子樹之后

// 二叉樹后序遍歷
void BinaryTreePostOrder(BTNode* root)
{if (root == NULL){printf("NULL ");return;}BinaryTreePostOrder(root->_left);BinaryTreePostOrder(root->_right);printf("%d ",root->_data);
}

?層序遍歷:除了先序遍歷、中序遍歷、后序遍歷外,還可以對二叉樹進行層序遍歷。設二叉樹的根節點所在 層數為1,層序遍歷就是從所在二叉樹的根節點出發,首先訪問第一層的樹根節點,然后從左到右訪問第2層 上的節點,接著是第三層的節點,以此類推,自上而下,自左至右逐層訪問樹的結點的過程就是層序遍歷。

// 層序遍歷
#include"Queue.h"
void BinaryTreeLevelOrder(BTNode* root)
{Queue q;QueueInit(&q);if (root)QueuePush(&q, root);while (!QueueEmpty(&q)){BTNode* Fout = QueueFront(&q);QueuePop(&q);printf("%d ",Fout->_data);if (Fout->_left){QueuePush(&q,Fout->_left);}if (Fout->_right){QueuePush(&q, Fout->_right);}}QueueDestroy(&q);
}

判斷二叉樹是否是完全二叉樹

// 判斷二叉樹是否是完全二叉樹
bool BinaryTreeComplete(BTNode* root)
{Queue q;QueueInit(&q);if (root)QueuePush(&q, root);while (!QueueEmpty(&q)){BTNode* Fout = QueueFront(&q);QueuePop(&q);if (Fout == NULL){break;}QueuePush(&q, Fout->_left);QueuePush(&q, Fout->_right);}while (!QueueEmpty(&q)){BTNode* Fout = QueueFront(&q);QueuePop(&q);if (root){QueueDestroy(&q);return false;}}QueueDestroy(&q);return true;
}

?二叉樹節點和高度等

1.二叉樹節點個數?

// 二叉樹節點個數
int BinaryTreeSize(BTNode* root)
{return root == NULL ? 0 : BinaryTreeSize(root->_left) + BinaryTreeSize(root->_left)+1;
}

2.二叉樹葉子節點個數

// 二叉樹葉子節點個數
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);
}

3.二叉樹的最大高度

//二叉樹的最大高度
int TreeHeight(BTNode* root) 
{if (root == NULL)return 0;int node_left=TreeHeight(root->_left); int node_right = TreeHeight(root->_right);return node_left > node_right ? node_left + 1 : node_right + 1;
}

4.二叉樹第k層節點個數

// 二叉樹第k層節點個數
int BinaryTreeLevelKSize(BTNode* root, int k)
{if (root == NULL)return 0;if (k == 1)return 1;return BinaryTreeLevelKSize(root->_left, k - 1) + BinaryTreeLevelKSize(root->_right, k - 1);
}

5.二叉樹查找值為x的節點

// 二叉樹查找值為x的節點
BTNode* BinaryTreeFind(BTNode* root, BTDataType x)
{if (root == NULL)return NULL;if (root->_data == x)return root;BTNode* ret1 = BinaryTreeFind(root->_left, x);if (ret1)return ret1;BTNode* ret2 = BinaryTreeFind(root->_right, x);if (ret2)return ret2;return NULL;}

?二叉樹銷毀

// 二叉樹銷毀
void BinaryTreeDestory(BTNode** root)
{if (*(root) == NULL)return;BinaryTreeDestory(&(*root)->_left);BinaryTreeDestory(&(*root)->_right);free(*(root));
}

三、鏈式二叉樹的練習

相同的樹?

給你兩棵二叉樹的根節點?p?和?q?,編寫一個函數來檢驗這兩棵樹是否相同。

如果兩個樹在結構上相同,并且節點具有相同的值,則認為它們是相同的。

思路:? 可以通過遞歸的方式同時遍歷兩棵樹。

比較兩棵樹的根節點值是否相等,如果不相等則直接返回 false。

然后遞歸地對左子樹和右子樹分別進行相同的比較,只有當左右子樹在相應位置上都相同的時候才返回 true。

在遞歸過程中,只要有一處不滿足相同條件就可以立即返回 false,只有所有節點和結構都完全一致才能最終返回 true。

/*** Definition for a binary tree node.* struct TreeNode {*     int val;*     struct TreeNode *left;*     struct TreeNode *right;* };*/
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);
}

對稱二叉樹

給你一個二叉樹的根節點?root?, 檢查它是否軸對稱。?

思路:

采用遞歸的方法。

一個二叉樹是軸對稱的,意味著對于任意一個節點,它的左子樹和右子樹是鏡像對稱的。

具體來說,就是對于當前節點,它的左子節點和右子節點的值相等(如果都存在的話),并且左子節點的左子樹和右子節點的右子樹對稱,左子節點的右子樹和右子節點的左子樹也對稱。我們通過遞歸地比較左右子樹的對應節點來判斷整個二叉樹是否對稱。如果在遞歸過程中發現不滿足對稱條件的情況,就可以返回 false,如果遞歸完整棵樹都滿足,則返回 true。

 * Definition for a binary tree node.* struct TreeNode {*     int val;*     struct TreeNode *left;*     struct TreeNode *right;* };*/
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) {return _isSymmetric(root->left, root->right);
}

?另外一顆子樹

給你兩棵二叉樹?root?和?subRoot?。檢驗?root?中是否包含和?subRoot?具有相同結構和節點值的子樹。如果存在,返回?true?;否則,返回?false?。

二叉樹?tree?的一棵子樹包括?tree?的某個節點和這個節點的所有后代節點。tree?也可以看做它自身的一棵子樹。

思路

我們可以從根節點開始,對主樹 root 進行先序遍歷。

在遍歷過程中,每當遇到一個節點,就判斷以這個節點為根的子樹是否與 subRoot 完全相同。

為了判斷子樹是否相同,可以編寫一個輔助函數來比較兩棵樹是否完全一致,這與前面判斷兩棵樹是否相同的思路類似,即同時遞歸地檢查節點值以及左右子樹的結構和節點值是否匹配。如果找到匹配的子樹,就返回 true,否則繼續遍歷主樹的其他節點。

/*** Definition for a binary tree node.* struct TreeNode {*     int val;*     struct TreeNode *left;*     struct TreeNode *right;* };*/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);
}
bool isSubtree(struct TreeNode* root, struct TreeNode* subRoot)
{if(root==NULL)return false;if( root->val==subRoot->val &&isSameTree(root,subRoot))return true;return isSubtree(root->left,subRoot)||isSubtree(root->right,subRoot);
}

二叉樹前序遍歷?

給你二叉樹的根節點?root?,返回它節點值的?前序?遍歷。

思路:

首先訪問根節點,然后遞歸地對左子樹進行前序遍歷,最后遞歸地對右子樹進行前序遍歷。

具體來說,我們可以使用一個輔助函數,在這個函數中先輸出當前節點的值,然后如果左子樹存在就對左子樹調用該函數進行遞歸遍歷,接著如果右子樹存在就對右子樹調用該函數進行遞歸遍歷。這樣就可以按照前序遍歷的順序輸出所有節點的值。

/*** Definition for a binary tree node.* struct TreeNode {*     int val;*     struct TreeNode *left;*     struct TreeNode *right;* };*/
/*** Note: The returned array must be malloced, assume caller calls free().*/
int TreeSize(struct TreeNode* root) {return root == NULL ? 0 : TreeSize(root->left) + TreeSize(root->right) + 1;
}
void PrevOrder(struct TreeNode* root,int* a,int* i)
{if(root==NULL)return;a[(*i)++]=root->val;PrevOrder(root->left,a,i);PrevOrder(root->right,a,i);
}
int* preorderTraversal(struct TreeNode* root, int* returnSize) 
{* returnSize=TreeSize(root);int* a=(int*)malloc(sizeof(int)*(*returnSize));int i = 0;PrevOrder(root,a,&i);return a;
}

?二叉樹遍歷

編一個程序,讀入用戶輸入的一串先序遍歷字符串,根據此字符串建立一個二叉樹(以指針方式存儲)。 例如如下的先序遍歷字符串: ABC##DE#G##F### 其中“#”表示的是空格,空格字符代表空樹。建立起此二叉樹以后,再對二叉樹進行中序遍歷,輸出遍歷結果。

輸入描述:

輸入包括1行字符串,長度不超過100。

輸出描述:

可能有多組測試數據,對于每組數據, 輸出將輸入字符串建立二叉樹后中序遍歷的序列,每個字符后面都有一個空格。 每個輸出結果占一行。

思路:

1. 定義二叉樹節點結構體:包含節點值以及左右子節點指針。

2. 構建二叉樹函數:通過遍歷輸入的先序遍歷字符串來構建二叉樹。使用一個靜態索引來跟蹤當前處理的字符位置。如果遇到非'#'字符,就創建一個新節點,然后遞歸地構建左子樹和右子樹,遇到'#'則表示空節點。

3. 中序遍歷函數:按照中序遍歷的順序(先左子樹、當前節點、再右子樹)輸出節點值并添加空格。

4. 在主程序中,獲取用戶輸入的字符串,調用構建二叉樹函數得到二叉樹,然后調用中序遍歷函數輸出結果。

#include<stdio.h>
#include<stdlib.h>typedef struct Tree {struct Tree* le;struct Tree* ri;int val;
} BTNode;void PrevInor(BTNode* root) 
{if (root == NULL)return;PrevInor(root->le);printf("%c ", root->val);PrevInor(root->ri);
}BTNode* BUTree(char* a,int* pi)
{if(a[*pi] =='#'){(*pi)++;return NULL;}BTNode* newnode=(BTNode*)malloc(sizeof(BTNode));newnode->val=a[(*pi)++];newnode->le=BUTree(a, pi);newnode->ri=BUTree(a, pi);return newnode;
}
int main()
{char a[100];scanf("%s",a);int i=0;BTNode* node=BUTree(a, &i);PrevInor(node);
}

四、完整代碼

Tree.h

#include<stdio.h>
#include<stdlib.h>
#include<assert.h>
#include<stdbool.h>typedef int BTDataType;
typedef struct BinaryTreeNode
{BTDataType _data;struct BinaryTreeNode* _left;struct BinaryTreeNode* _right;
}BTNode;// 通過前序遍歷的數組"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);
// 判斷二叉樹是否是完全二叉樹
bool BinaryTreeComplete(BTNode* root);
BTNode* BuyNode(BTDataType x);//求二叉樹的最長高度
int TreeHeight(BTNode* root);

Tree.c

#define _CRT_SECURE_NO_WARNINGS
#include"Tree.h"BTNode* BuyNode(BTDataType x)
{BTNode* newnode = (BTNode*)malloc(sizeof(BTNode));if (newnode == NULL){perror("malloc err");return NULL;}newnode->_data = x;newnode->_left = NULL;newnode->_right = NULL;return newnode;
}/*int n,*/
// 通過前序遍歷的數組"ABD##E#H##CF##G##"構建二叉樹
BTNode* BinaryTreeCreateChar(BTDataType* a, int* pi)
{if (a[(*pi)] == '#'){(*pi)++;return NULL;}BTNode* newnode = (BTNode*)malloc(sizeof(BTNode));if (newnode == NULL){perror("malloc err");return NULL;}newnode->_data = a[(*pi)++];newnode->_left = BinaryTreeCreateChar(a, pi);newnode->_right = BinaryTreeCreateChar(a, pi);return newnode;
}//123nn4n5nn67nn8nn
BTNode* BinaryTreeCreate()
{BTNode* node1 = BuyNode(1);BTNode* node2 = BuyNode(2);BTNode* node3 = BuyNode(3);BTNode* node4 = BuyNode(4);BTNode* node5 = BuyNode(5);BTNode* node6 = BuyNode(6);BTNode* node7 = BuyNode(7);BTNode* node8 = BuyNode(8);node1->_left = node2;node1->_right = node6;node2->_left = node3;node2->_right = node4;node4->_right = node5;node6->_left = node7;node6->_right = node8;return node1;
}
// 二叉樹銷毀
void BinaryTreeDestory(BTNode** root)
{if (*(root) == NULL)return;BinaryTreeDestory(&(*root)->_left);BinaryTreeDestory(&(*root)->_right);free(*(root));
}
// 二叉樹節點個數
int BinaryTreeSize(BTNode* root)
{return root == NULL ? 0 : BinaryTreeSize(root->_left) + BinaryTreeSize(root->_left)+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)
{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->_left, x);if (ret1)return ret1;BTNode* ret2 = BinaryTreeFind(root->_right, x);if (ret2)return ret2;return NULL;}
// 二叉樹前序遍歷 
void BinaryTreePrevOrder(BTNode* root)
{if (root == NULL){printf("NULL ");return;}printf("%d ", root->_data);BinaryTreePrevOrder(root->_left);BinaryTreePrevOrder(root->_right);
}
// 二叉樹中序遍歷
void BinaryTreeInOrder(BTNode* root)
{if (root == NULL){printf("NULL ");return;}BinaryTreeInOrder(root->_left);printf("%d ",root->_data);BinaryTreeInOrder(root->_right);
}
// 二叉樹后序遍歷
void BinaryTreePostOrder(BTNode* root)
{if (root == NULL){printf("NULL ");return;}BinaryTreePostOrder(root->_left);BinaryTreePostOrder(root->_right);printf("%d ",root->_data);
}
// 層序遍歷
#include"Queue.h"
void BinaryTreeLevelOrder(BTNode* root)
{Queue q;QueueInit(&q);if (root)QueuePush(&q, root);while (!QueueEmpty(&q)){BTNode* Fout = QueueFront(&q);QueuePop(&q);printf("%d ",Fout->_data);if (Fout->_left){QueuePush(&q,Fout->_left);}if (Fout->_right){QueuePush(&q, Fout->_right);}}QueueDestroy(&q);
}
// 判斷二叉樹是否是完全二叉樹
bool BinaryTreeComplete(BTNode* root)
{Queue q;QueueInit(&q);if (root)QueuePush(&q, root);while (!QueueEmpty(&q)){BTNode* Fout = QueueFront(&q);QueuePop(&q);if (Fout == NULL){break;}QueuePush(&q, Fout->_left);QueuePush(&q, Fout->_right);}while (!QueueEmpty(&q)){BTNode* Fout = QueueFront(&q);QueuePop(&q);if (root){QueueDestroy(&q);return false;}}QueueDestroy(&q);return true;
}//二叉樹的最大高度
int TreeHeight(BTNode* root) 
{if (root == NULL)return 0;int node_left=TreeHeight(root->_left); int node_right = TreeHeight(root->_right);return node_left > node_right ? node_left + 1 : node_right + 1;
}

Queue.c(部分)

void QueueInit(Queue* pq)
{assert(pq);pq->phead = NULL;pq->ptail = NULL;pq->size = 0;
}
void QueueDestroy(Queue* pq)
{assert(pq);QNode* cur = pq->phead;while (cur){QNode* next = cur->next;free(cur);cur = next;}pq->phead = pq->ptail = NULL;pq->size = 0;
}
void QueuePush(Queue* pq, QDataType x)
{assert(pq);QNode* newnode = (QNode*)malloc(sizeof(QNode));if (newnode == NULL){perror("malloc err");return;}newnode->data = x;newnode->next=NULL;if (pq->phead == NULL){assert(pq->ptail == NULL);pq->phead = pq->ptail= newnode;}else{pq->ptail->next = newnode;pq->ptail = newnode;}pq->size++;
}
void QueuePop(Queue* pq)
{assert(pq);assert(!QueueEmpty(pq));if (pq->phead->next == NULL){free(pq->phead);pq->phead = pq->ptail = NULL;}else {QNode* next = pq->phead->next;free(pq->phead);pq->phead = next;}pq->size--;
}
QDataType QueueFront(Queue* pq)
{assert(pq);assert(!QueueEmpty(pq));return pq->phead->data;
}
bool QueueEmpty(Queue* pq)
{assert(pq);return pq->phead == NULL&& pq->ptail == NULL;
}

五、總結

二叉樹全面總結:

定義:
二叉樹是一種特殊的樹結構,每個節點最多有兩個子節點,分別稱為左子節點和右子節點。

主要特點:

? 節點度最大為 2。

? 具有遞歸結構。

重要類型:

? 滿二叉樹:所有節點都有兩個子節點,且葉子節點都在同一層。

? 完全二叉樹:除了最后一層,其他層都是滿的,最后一層的葉子節點靠左排列。

遍歷方式:

? 前序遍歷:先訪問根節點,再遍歷左子樹,最后遍歷右子樹。

? 中序遍歷:先遍歷左子樹,再訪問根節點,最后遍歷右子樹。

? 后序遍歷:先遍歷左子樹,再遍歷右子樹,最后訪問根節點。

? 層次遍歷:按照層次依次訪問節點。

應用:

? 高效搜索和排序。

? 表達式樹。

? 二叉堆實現優先隊列等。

性質:

? 在完全二叉樹中,節點編號與層次存在特定關系。

? 葉子節點數與度為 2 的節點數存在一定關系。

存儲方式:

? 鏈式存儲:通過節點指針連接。

? 數組存儲:適用于完全二叉樹。

常見算法:

? 構建二叉樹。

? 求深度、高度。

? 查找節點。

? 平衡性判斷及調整(如 AVL 樹、紅黑樹等)。

二叉樹是數據結構中的基礎且重要部分,在計算機科學中有廣泛的應用和研究價值。

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/bicheng/15973.shtml
繁體地址,請注明出處:http://hk.pswp.cn/bicheng/15973.shtml
英文地址,請注明出處:http://en.pswp.cn/bicheng/15973.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

Linux服務升級:Predixy 升級代理 Redis-cluster 集群

目錄 一、實驗 1.環境 2. 啟動Redis服務 3.Predixy 升級代理 Redis-cluster 集群 二、問題 1. Predixy進行set操作報錯 2.如何創建腳本啟動predixy 3.Redis代理對比 一、實驗 1.環境 &#xff08;1&#xff09;主機 表1 主機 系統版本節點軟件IP備注CentOS7.9Redis…

Springboot開發 -- Postman 調試類型詳解

引言 在 Spring Boot 應用開發過程中&#xff0c;接口測試是必不可少的一環。Postman 作為一款強大的 API 開發和測試工具&#xff0c;可以幫助開發者輕松構建、測試和管理 HTTP 請求。本文將為大家介紹如何在 Spring Boot 開發中使用 Postman 進行接口測試。 一、準備工作 安…

C/C++|malloc分配內存詳解

看本節前&#xff0c;希望讀者有linux內存分布的基本概念&#xff0c;可以閱讀這篇文章&#xff1a; 進程虛擬地址空間和函數調用棧 在本節中希望讀者可以一口氣閱讀完所有內容。 本博客內容全部來自小林coding&#xff1a;malloc 是如何分配內存的&#xff1f; 這里僅為筆記記…

Python-圖片旋轉360,保存對應圖片

#Author &#xff1a;susocool #Creattime:2024/5/25 #FileName:turn360 #Description: 會旋轉指定的圖像文件360度&#xff0c;并將每個旋轉后的圖像保存到指定目錄&#xff0c;文件名以旋轉角度命名。 from PIL import Imagedef rotate_and_save(image_path, output_dir) :# …

Linux/Ubuntu 中安裝 ZeroTier,實現內網穿透,2分鐘搞定

相信很多人都有遠程連接家中設備的需求&#xff0c;如遠程連接家中的NAS、Windows等服務&#xff0c;所以會涉及到一個內網穿透工具的使用&#xff0c;如果沒有公網IP的情況下&#xff0c;推薦大家使用ZeroTier&#xff0c;這是一款強大的內網穿透工具。 mac和windows版的操作…

Nginx-狂神說

Nginx概述 公司產品出現瓶頸&#xff1f; 我們公司項目剛剛上線的時候&#xff0c;并發量小&#xff0c;用戶使用的少&#xff0c;所以在低并發的情況下&#xff0c;一個jar包啟動應用就夠了&#xff0c;然后內部tomcat返回內容給用戶。 但是慢慢的&#xff0c;使用我們平臺…

HTTP 各版本差異

http1.0 它的特點是每次請球和響應完畢后都會銷毀TCP 連接。同時規走前一個響應完成后才發送下一個請求。這樣做有兩個問題&#xff1a; 無法復用連接了。 每次請求都要創建新的TCP連接&#xff0c;完成三次握手和四次揮手。網絡利用率低 隊頭阻塞 如果前一個請求被某種原因阻…

K8S認證|CKA題庫+答案| 13. sidecar 代理容器日志

目錄 13、使用 sidecar 代理容器日志 CKA v1.29.0模擬系統免費下載試用&#xff1a; 題目&#xff1a; 開始操作&#xff1a; 1&#xff09;、切換集群 2&#xff09;、生成yaml文件 3&#xff09;、官網找模板 4&#xff09;、編輯yaml文件 5&#xff09;、應用yaml…

車載電子電器架構 —— 智能座艙技術

車載電子電器架構 —— 智能座艙技術 我是穿拖鞋的漢子&#xff0c;魔都中堅持長期主義的汽車電子工程師。 老規矩&#xff0c;分享一段喜歡的文字&#xff0c;避免自己成為高知識低文化的工程師&#xff1a; 屏蔽力是信息過載時代一個人的特殊競爭力&#xff0c;任何消耗你的…

qt multiple definition of 報錯解決

qt編譯報了很多錯&#xff0c; multiple definition of xxx 原來一維設計文件ui 的問題 后來發現是pro中頭文件和cpp文件重寫了&#xff0c;導致重復編譯報的錯 解決方法&#xff1a;把重復的頭文件和cpp文件刪了就可以了。

如何解決0.1+0.2!=0.3的問題

var x 0.1; var y 0.2; var z x y // z 的結果為 0.30000000000000004 if (z 0.3) // 返回 false 可以用整數的乘除法來解決 var z (x * 10 y * 10) / 10; // z 的結果為 0.3

GEO數據挖掘-GEO背景知識+表達芯片分析思路

From生物技能樹 GEO數據挖掘第一節 &#xff08;pipeline&#xff09; 文章目錄 1.圖表分析2.GEO背景介紹及分析思路3.代碼分析流程4.復雜數據分析理論知識1.數據從哪里來2.有什么類型的數據可挖掘3.如何篩選基因&#xff08;分析方法&#xff09;在這里插入圖片描述 圖表介紹1…

Jenkins + github 自動化部署配置

1 Jenkins安裝 AWS EC2安裝Jenkins&#xff1a;AWS EC2 JDK11 Jenkins-CSDN博客 AWS EC2上Docker安裝Jenkins&#xff1a;https://blog.csdn.net/hhujjj2005/article/details/139078402 2 登錄jenkins http://192.168.1.128:8080/ $ docker exec -it d1851d9e3386 /bin/ba…

Multi-objective reinforcement learning approach for trip recommendation

Multi-objective reinforcement learning approach for trip recommendation A B S T R A C T 行程推薦是一項智能服務&#xff0c;為游客在陌生的城市提供個性化的行程規劃。 它旨在構建一系列有序的 POI&#xff0c;在時間和空間限制下最大化用戶的旅行體驗。 將候選 POI 添…

【Shell】sed編輯器實例

sed是用來解析和轉換文本的工具&#xff0c;它使用簡單&#xff0c;是簡潔的程序設計語言。 sed編輯器 &#xff08;一&#xff09; sed編輯器基礎1. 簡介2. sed的模式空間 &#xff08;二&#xff09;基本的sed編輯命令&#xff08;三&#xff09;sed命令實例1. 向文件中添加或…

MFC GDI 繪圖模式、映射模式、畫筆、筆、字體

一 GDI 繪圖模式&#xff08;RoP2 Mode&#xff09; 在使用VC MFC進行圖形程序編程時&#xff0c;常會用到GDI繪圖指令&#xff0c;而要做到繪圖時有橡皮筋動態效果&#xff0c;就需設置GDI繪圖模式。GDI繪圖模式有多種&#xff0c;如下&#xff1a; 常用R2_NOT模式來實…

Linux|操作系統|如何下載各個版本的centos操作系統

前言&#xff1a; centos做為一個現在比較常用的Linux社區版本&#xff0c;還是比較受歡迎的&#xff0c;那么&#xff0c;如何下載centos的安裝包&#xff0c;也就是centos的操作系統呢&#xff1f; 首先&#xff0c;我們應該知道硬件底層有aarch64&#xff0c;ppc64&#x…

【限免】短時傅里葉變換時頻分析【附MATLAB代碼】

來源&#xff1a;微信公眾號&#xff1a;EW Frontier 簡介 一種能夠同時對信號時域和頻域分析的方法——短時傅里葉變換&#xff08;STFT&#xff09;&#xff0c;可以在時頻二維角度準確地描述信號 的時間、頻域的局部特性&#xff0c;與其他算法不同&#xff0c;通過該算法可…

【Elasticsearch】Centos7安裝Elasticsearch、kibana、IK分詞

目錄 本文安裝包下載地址注意安裝elasticsearch1.上傳文件2.解壓elasticsearch-6.3.1.tar.gz3.開啟遠程連接權限4.修改其他配置[root用戶操作]5.重啟虛擬機6.啟動es7.外部訪問 安裝kibana-61.解壓2.配置3.啟動kibana4.訪問5.在開發工具中做數據的增刪改查操作 安裝IK分詞1.wind…

簡述什么是Vue的自定義指令

Vue的自定義指令是Vue框架提供的一種擴展機制&#xff0c;允許開發者注冊自己的指令&#xff0c;從而封裝一些DOM操作或添加額外的功能。這些自定義指令可以在Vue模板中像內置指令&#xff08;如v-for、v-if等&#xff09;一樣使用&#xff0c;但提供了更大的靈活性和自定義性。…