c# 數據結構 樹篇 入門樹與二叉樹的一切

? ? ? ? 事先聲明,本文不適合對數據結構完全不懂的小白 請至少學會鏈表再閱讀

????????c# 數據結構 鏈表篇 有關單鏈表的一切_c# 鏈表-CSDN博客

數據結構理論先導:《數據結構(C 語言描述)》也許是全站最良心最通俗易懂最好看的數據結構課(最遲每周五更新~~)_嗶哩嗶哩_bilibili

代碼隨想錄:

關于二叉樹,你該了解這些!| 二叉樹理論基礎一網打盡,二叉樹的種類、二叉樹的存儲方式、二叉樹節點定義、二叉樹的遍歷順序_嗶哩嗶哩_bilibili

????????

目錄

0.樹基礎概念

1.二叉樹基礎概念 BT B:Binary?

?編輯

2.普通二叉樹存儲/遍歷/缺點

?存儲方式

順序存儲:

?鏈式存儲:

遍歷方式

順序存儲遍歷(遞歸)

鏈式存儲遍歷(遞歸)

插入方式及其缺點

? ? ? ? 鏈式存儲插入

? ? ? ? 缺點

3.二叉搜索樹 BST S:Search

? ? ? ? 鏈式構建及其增刪查改

? ? ? ? 測試用例以及全部代碼

4.平衡二叉樹(AVL) BBT:? ?B:Balanced

? ? ? ? 構建和插入

? ? ? ? 刪除

5.二叉樹的線索化? ? ?

5.1設計線索化結構

5.2 線索化構建樹?

5.3 線索化后中序遍歷方法舉例

? ?關于紅黑樹和b+樹 下一篇數據結構 樹篇 將會做出徹底詳解?


0.樹基礎概念

????????0和1是基礎概念和一些性質 可以看個大概 知道有這么回事就行了 后面用到再回來想想是不是這么回事即可?

?葉子節點也算是子樹?

樹的性質

?解釋:

結點的度 = 該節點下最大子樹個數,也就是看有幾個孩子

比如:A結點 有三個子樹 即為三個孩子 ,B有兩個孩子,K無孩子

解釋:?

還是這棵樹 i =1開始?

樹的度 = 最大結點的度,也就是有最多孩子結點的度

還是上面這棵樹 最多孩子的度為A||D 所以 m = 3

第一層就是3的0次方 =1

第二層就是3的1次方 =3

第三層就是3的二次方 =9 (最大值)

1.二叉樹基礎概念 BT B:Binary?

?解釋:

對于這個性質的解釋:


?

2.普通二叉樹存儲/遍歷/缺點

?存儲方式

順序存儲:

????????順序存儲需要注意的是讓索引 i 從0

????????

? ? ? ? 特點是:依據其索引的特點 通過線性結構存儲起來

????????我用的是List(i=0開始)

public class Tree<T> : MonoBehaviour
{private List<T> bitTree = new List<T>();public void AddTree(T[] values){for(int i = 0; i < values.Length; i++){bitTree.Add(values[i]);}}
}
     Tree<char> tree = new Tree<char>();char[] values = { 'A', 'B', 'C', 'D' };tree.AddTree(values);

?鏈式存儲:

特點為 =左右孩子指針 + 數據存儲位

//節點暫時定義為char
public class TreeNode {public char Date;public TreeNode LeftNode;public TreeNode RightNode;public TreeNode(char Date, TreeNode LeftNode=null, TreeNode RightNode=null) {this.Date = Date;this.LeftNode =LeftNode;this.RightNode = RightNode;}

遍歷方式

有三種分為前中后序

?前序特點:

就是先當前節點(如果從根節點開始),再左節點再右節點

中序特點:

先左,再當前,最后右

后序特點:

先左,再右,最后當前

順序存儲遍歷(遞歸)

以前序為例 先構造樹

再做遞歸

    //順序遍歷二叉樹//前序public void Preorder(int index){if (index >= bitTree.Count)return;Debug.Log(bitTree[index]);int LeftNode = 2*index+1;int  RightNode = 2*index+2;Preorder(LeftNode);Preorder(RightNode);}//中序public void MiddleOrder(int index){if (index >= bitTree.Count)return;int LeftNode = 2 * index + 1;int RightNode = 2 * index + 2;MiddleOrder(LeftNode);Debug.Log(bitTree[index]);MiddleOrder(RightNode);}//后序public void AfterOrder(int index) {if (index >= bitTree.Count)return;int LeftNode = 2 * index + 1;int RightNode = 2 * index + 2;AfterOrder(LeftNode);AfterOrder(RightNode);Debug.Log(bitTree[index]);}

鏈式存儲遍歷(遞歸)

還是以前序遍歷為例:

TreeNode rootNode = new TreeNode('A',new TreeNode('B',new TreeNode('D'), new TreeNode('E')),new TreeNode('C', new TreeNode('F')));rootNode.FirstRoot(rootNode);
Console.WriteLine();rootNode.MiddleRoot(rootNode);
Console.WriteLine();rootNode.AfterRoot(rootNode);
//節點暫時定義為char
public class TreeNode {public char Date;public TreeNode LeftNode;public TreeNode RightNode;public TreeNode(char Date, TreeNode LeftNode=null, TreeNode RightNode=null) {this.Date = Date;this.LeftNode =LeftNode;this.RightNode = RightNode;}//遍歷方法 前public void FirstRoot(TreeNode treeNode){if (treeNode == null) return;Console.Write(treeNode.Date);FirstRoot(treeNode.LeftNode);FirstRoot(treeNode.RightNode);}//遍歷方法 中public void MiddleRoot(TreeNode treeNode){if (treeNode == null) return;Console.Write(treeNode.Date);MiddleRoot(treeNode.LeftNode);MiddleRoot(treeNode.RightNode);}  //遍歷方法 后public void AfterRoot(TreeNode treeNode){if (treeNode == null) return;AfterRoot(treeNode.LeftNode);AfterRoot(treeNode.RightNode);Console.Write(treeNode.Date);}
}

插入方式及其缺點

? ? ? ? 鏈式存儲插入

? ? ? ? 我想給原來的二叉樹的 2 6之間插入一個4


TreeNode root = new TreeNode(1);
root.LeftNode = new TreeNode(2);
root.RightNode = new TreeNode(3);
root.LeftNode.LeftNode = new TreeNode(6);
root.LeftNode.RightNode = new TreeNode(7);//節點暫時定義為char
public class TreeNode
{public int Date;public TreeNode LeftNode;public TreeNode RightNode;public TreeNode(int Date, TreeNode LeftNode = null, TreeNode RightNode = null){this.Date = Date;this.LeftNode = LeftNode;this.RightNode = RightNode;} 

我需要做的

// 創建新節點
TreeNode newNode = new TreeNode(4);// 在節點 2 的左子節點位置插入新節點 4
BinaryTree.InsertNode(root.LeftNode, true, newNode);
 public class BinaryTree{/// <summary>/// 值插入/// </summary>/// <param name="parent"></param>/// <param name="isLeft">是否是左子節點</param>/// <param name="newNode"></param>public static void InsertNode(TreeNode parent, bool isLeft, TreeNode newNode){if (isLeft){newNode.LeftNode = parent.LeftNode;parent.LeftNode = newNode;}else{newNode.RightNode = parent.RightNode;parent.RightNode = newNode;}}}

? ? ? ? 缺點

????????發現了沒有和他娘的鏈表似的:?

????????無法利用 “值的順序” 進行高效操作??

????????比如搜索某個值(如查找?4)時,只能從根節點開始遍歷整個樹(如廣度優先或深度優先搜索),時間復雜度為?O(n),和鏈表無異

?????????插入邏輯不通用:插入節點?4?到節點?2?的左子節點,依賴于手動指定父子關系,沒有統一的規則,如果樹結構復雜,插入位置的選擇會非常隨意,導致樹的高度不平衡(如退化成鏈表)

? ? ? ? 于是有了下面這個玩意 二叉搜索樹

3.二叉搜索樹 BST S:Search

????????數據結構合集 - 二叉搜索樹(二叉排序樹)(二叉查找樹)_嗶哩嗶哩_bilibili

? ? ? ? 特點 左子樹Data小于根Data?? 右子樹Data 大于根Data

操作最好時間復雜度最壞時間復雜度
查找(Search)O(log n)O(n)
插入(Insert)O(log n)O(n)
刪除(Delete)O(log n)O(n)
空間復雜度O(n){O (n)(存儲所有節點,與樹的形態無關)}

? ? ? ? 存儲方式還是有鏈式和順序 我傾向于鏈式 因為比較簡單和清晰 所以拿此舉例

? ? ? ? 鏈式構建及其增刪查改

? ? ? ? ? ? 構建

public class TreeNode { public int value; public TreeNode Left; public TreeNode Right;public TreeNode(int value, TreeNode left = null, TreeNode right = null) {this.value = value;this.Left = left;this.Right = right;}
}public class BinarySearchTree
{public TreeNode root;public BinarySearchTree(){root = null;}

? ? ? ? 增加?

    //增加節點public void Insert(int value) { InsertTrueMethod(root, value);}/// <summary>/// 遞歸查找插入位置/// </summary>/// <param name="node">插入的節點</param>/// <param name="val">插入的值</param>private TreeNode InsertTrueMethod(TreeNode node, int value){if (node == null){return new TreeNode(value);}//如果插入值 小于 節點值,則在左子樹中插入if (value < node.value){node.Left = InsertTrueMethod(node.Left, value);}//如果插入值 大于 節點值,則在右子樹中插入else if (value > node.value){node.Right = InsertTrueMethod(node.Right, value);}//如果找到了相同的值,則不插入return node;}

? ? ? ? 刪除

    private TreeNode DeleteTrueMethod(TreeNode node, int value){//如果樹為空,則直接返回空if (node == null){return null;}//如果刪除值 小于 節點值,則在左子樹找if (value < node.value){node.Left = DeleteTrueMethod(node.Left, value);}//如果刪除值 大于 節點值,則在右子樹else if (value > node.value){node.Right = DeleteTrueMethod(node.Right, value);}//如果找到了相同的值,則刪除該節點else{//如果該節點沒有子節點,則直接刪除該節點if (node.Left == null && node.Right == null){node = null;}//如果該節點只有一個子節點,則直接用該節點的子節點替換該節點else if (node.Left == null){node = node.Right;}else if (node.Right == null){node = node.Left;}// 如果該節點有兩個子節點,此時有兩種常見的替換策略:// 可以選擇該節點右子樹中的最小節點,也可以選擇左子樹中的最大節點。// 這里我們采用選擇右子樹中最小節點的策略。選擇右子樹最小節點(或者左子樹最大節點)的目的是// 為了保證替換后仍然滿足二叉搜索樹的性質:左子樹所有節點值小于根節點值,右子樹所有節點值大于根節點值。// 步驟為:先找到右子樹的最小節點,用其值替換當前要刪除節點的值,// 然后再遞歸地從右子樹中刪除這個最小節點。else{TreeNode minNode = GetMinNode(node.Right);node.value = minNode.value;node.Right = DeleteTrueMethod(node.Right, minNode.value);}}return node;}//獲取節點方法private TreeNode GetMinNode(TreeNode node){while (node.Left != null){node = node.Left;}return node;}

? ? ? ? 測試用例以及全部代碼

? ? ? ? 注釋進行了簡單的修改

using System;
BinarySearchTree bst = new BinarySearchTree();// 測試用例 1:刪除葉子節點
int[] values1 = { 50, 30, 20, 40, 70, 60, 80 };
foreach (var val in values1) bst.Insert(val);
//Console.WriteLine("刪除前(用例1):");
//bst.InOrderTraversal(bst.root); // 輸出:20 30 40 50 60 70 80 
//bst.Delete(20);
//Console.WriteLine("刪除后(用例1-葉子節點):");
//bst.InOrderTraversal(bst.root); // 預期:30 40 50 60 70 80 測試用例 2:刪除單子節點
//BinarySearchTree bst2 = new BinarySearchTree();
//int[] values2 = { 50, 30, 40 };
//foreach (var val in values2) bst2.Insert(val);
//bst2.Delete(30);
//Console.WriteLine("刪除后(用例2-單子節點):");
//bst2.InOrderTraversal(bst2.root); // 預期:40 50 測試用例 3:刪除雙子節點
BinarySearchTree bst3 = new BinarySearchTree();
int[] values3 = { 50, 30, 20, 40, 70, 60, 80 };
foreach (var val in values3) bst3.Insert(val);
bst3.Delete(50);
Console.WriteLine("刪除后(用例3-雙子節點):");
bst3.InOrderTraversal(bst3.root); // 預期:20 30 40 60 70 80 
public class TreeNode
{public int value;public TreeNode Left;public TreeNode Right;public TreeNode(int value, TreeNode left = null, TreeNode right = null){this.value = value;this.Left = left;this.Right = right;}
}public class BinarySearchTree
{public TreeNode root;public BinarySearchTree(){root = null;}// 增加節點public void Insert(int value){root = InsertTrueMethod(root, value); }private TreeNode InsertTrueMethod(TreeNode node, int value){if (node == null)return new TreeNode(value);if (value < node.value)node.Left = InsertTrueMethod(node.Left, value);else if (value > node.value)node.Right = InsertTrueMethod(node.Right, value);return node;}public void Delete(int value){root = DeleteTrueMethod(root, value);}private TreeNode DeleteTrueMethod(TreeNode node, int value){//先找到待刪除節點if (node == null) return null;if (value < node.value)node.Left = DeleteTrueMethod(node.Left, value);else if (value > node.value)node.Right = DeleteTrueMethod(node.Right, value);else {//找到以后分為三種情況//1. 葉子節點if (node.Left == null && node.Right == null)node = null;//2. 單子節點else if (node.Left == null)node = node.Right;else if (node.Right == null)node = node.Left;else{//3. 雙子節點 找到右子樹最小節點(或者左子樹最大節點 替換待刪除節點 然后遞歸刪除右子樹最小節點, 或者左子樹最大節點)TreeNode minNode = GetRightMinNode(node.Right);node.value = minNode.value;node.Right = DeleteTrueMethod(node.Right, minNode.value);}}return node;}private TreeNode GetRightMinNode(TreeNode node){while (node.Left != null) node = node.Left;return node;}public void InOrderTraversal(TreeNode node){if (node == null) return;InOrderTraversal(node.Left);Console.Write(node.value + " "); InOrderTraversal(node.Right);if (node == root) Console.WriteLine(); }
}

? ? ? ? 但是還是有一個問題 如果數據本來就有序 那構建二叉搜索樹會成為一條線

?????????

? ? ? ? 所以為了解決這個問題 有了下面這個平衡二叉樹

4.平衡二叉樹(AVL) BBT:? ?B:Balanced

? ? ? ? 建議直接看視頻?平衡二叉樹(AVL樹)_嗶哩嗶哩_bilibili

? ? ? ? 這個東西是比較抽象的 而且情況也比較多 下圖來自 b站 @帕拉迪克

????????平衡因子:Balanced Factor

? ? ? ? 上代碼

? ? ? ? 構建和插入

using System;//測試結果
AVLTree tree = new AVLTree();
int[] values = { 5,3,4};foreach (int value in values) {tree.Insert(value);
}tree.InOrderTraversal(tree.root);
// 定義 AVL 樹節點類
public class TreeNode
{public int Value;       public TreeNode Left;     public TreeNode Right;    public int Height;        public TreeNode(int value){Value = value;Height = 1; // 新節點初始高度為1}
}public class AVLTree
{public TreeNode root;//獲取傳入節點的高度 private int GetHight(TreeNode node) { return node == null? 0 : node.Height;}//計算平衡因子 讓傳入節點的左子樹 - 右子樹高度 private int ComputeBalanceFactor(TreeNode node) { if(node == null ) return 0;int BalanceFactor = GetHight(node.Left) - GetHight(node.Right);return BalanceFactor;}//右旋 右旋父節點,然后將沖突的右放在旋轉后的父節點的左子樹private TreeNode RightRotate(TreeNode father) { //找到左子樹節點和新插入節點TreeNode leftChild = father.Left;TreeNode conflict = leftChild.Right;//旋轉leftChild.Right =  father; //原父節點弄到左子樹的右邊father.Left = conflict; //沖突的弄到原父節點的左邊//更新高度 先更新一下原來的父節點的高度 再更新一下現在的父節點的高度father.Height = Math.Max(GetHight(father.Left), GetHight(father.Right)) + 1;leftChild.Height = Math.Max(GetHight(leftChild.Left), GetHight(leftChild.Right)) + 1;//返回旋轉后的父節點return leftChild;}//左旋 左旋父節點,然后將沖突的左放在旋轉后的父節點的右子樹private TreeNode LeftRotate(TreeNode father){//找到右子樹節點和新插入節點TreeNode rightChild = father.Right;TreeNode conflict = rightChild.Left;//旋轉rightChild.Left = father; //原父節點弄到右子樹的左邊father.Right = conflict; //沖突的弄到原父節點的右邊//更新高度 先更新一下原來的父節點的高度 再更新一下現在的父節點的高度father.Height = Math.Max(GetHight(father.Left), GetHight(father.Right)) + 1;rightChild.Height = Math.Max(GetHight(rightChild.Left), GetHight(rightChild.Right)) + 1;//返回旋轉后的父節點return rightChild;}public void Insert(int value){root = InsertTrueMethod(root, value);}private TreeNode InsertTrueMethod(TreeNode root, int value){//BST插入 空創建 左右遞歸插入 重復值不插入if (root == null)return new TreeNode(value);if (value < root.Value)root.Left = InsertTrueMethod(root.Left, value); //遞歸+更新+平衡else if (value > root.Value)root.Right = InsertTrueMethod(root.Right, value);//遞歸+更新+平衡else return root;//更新高度root.Height = Math.Max(GetHight(root.Left), GetHight(root.Right)) + 1;//計算平衡因子int balanceFactor = ComputeBalanceFactor(root);//根據平衡因子判斷怎么轉//LL型 右旋  value < root.Left.Value:驗證新節點確實插入在左子樹的左側if (balanceFactor > 1 && value < root.Left.Value)return RightRotate(root);//RR型 左旋if (balanceFactor < -1 && value > root.Right.Value)return LeftRotate(root);//LR型 先左旋再右旋if (balanceFactor > 1 && value > root.Left.Value){root.Left = LeftRotate(root.Left);return RightRotate(root);}//RL型 先右旋再左旋if (balanceFactor < -1 && value < root.Right.Value){root.Right = RightRotate(root.Right);return LeftRotate(root);}//不用旋返回根節點return root;}//中序遍歷public void InOrderTraversal(TreeNode root){if (root == null)return;InOrderTraversal(root.Left);Console.WriteLine(root.Value);InOrderTraversal(root.Right);}
}

? ? ? ? 刪除

    // 刪除指定值的節點public void Delete(int value){root = DeleteNode(root, value);}private TreeNode DeleteNode(TreeNode root, int value){// 如果根節點為空,直接返回 nullif (root == null)return root;// 如果要刪除的值小于當前節點的值,遞歸刪除左子樹中的節點if (value < root.Value)root.Left = DeleteNode(root.Left, value);// 如果要刪除的值大于當前節點的值,遞歸刪除右子樹中的節點else if (value > root.Value)root.Right = DeleteNode(root.Right, value);// 找到要刪除的節點else{// 情況 1: 節點沒有子節點或只有一個子節點if (root.Left == null || root.Right == null){TreeNode temp = root.Left ?? root.Right;// 如果沒有子節點,直接刪除該節點if (temp == null){root = null;}else{// 用子節點替換當前節點root = temp;}}// 情況 2: 節點有兩個子節點else{// 找到右子樹中的最小節點TreeNode temp = MinValueNode(root.Right);// 用最小節點的值替換當前節點的值root.Value = temp.Value;// 遞歸刪除右子樹中的最小節點root.Right = DeleteNode(root.Right, temp.Value);}}// 如果刪除后樹為空,直接返回 nullif (root == null)return root;// 更新節點高度root.Height = Math.Max(GetHight(root.Left), GetHight(root.Right)) + 1;// 計算平衡因子int balanceFactor = ComputeBalanceFactor(root);// LL 型失衡,進行右旋操作if (balanceFactor > 1 && ComputeBalanceFactor(root.Left) >= 0)return RightRotate(root);// LR 型失衡,先對左子樹進行左旋,再對根節點進行右旋if (balanceFactor > 1 && ComputeBalanceFactor(root.Left) < 0){root.Left = LeftRotate(root.Left);return RightRotate(root);}// RR 型失衡,進行左旋操作if (balanceFactor < -1 && ComputeBalanceFactor(root.Right) <= 0)return LeftRotate(root);// RL 型失衡,先對右子樹進行右旋,再對根節點進行左旋if (balanceFactor < -1 && ComputeBalanceFactor(root.Right) > 0){root.Right = RightRotate(root.Right);return LeftRotate(root);}return root;}// 找到以給定節點為根的子樹中的最小節點private TreeNode MinValueNode(TreeNode node){TreeNode current = node;// 不斷向左遍歷,直到找到最左邊的節點while (current.Left != null)current = current.Left;return current;}

????????看起來有點難度實際上熟悉以后你會發現其編寫都是套路 多讀幾遍就好了

? ? ? ? 遞歸遞歸遞歸,你會發現二叉樹一直在做這個動作 那么有沒有一種方式脫離它呢?

????????有的兄弟 有的 :線索化二叉樹

5.二叉樹的線索化? ? ?

????????線索化二叉樹的設計思想是:

????????將空的指針(Left?或?Right)利用起來,不再指向子樹(因為子樹為空),而是指向該節點在中序遍歷中的前驅或后繼節點

????????這樣做可以在后續遍歷中,不依賴遞歸或棧,直接通過線索找到前后節點

? ? ? ? 畫圖,邏輯思想

? ? ? ? 下為代碼解釋

5.1設計線索化結構

????????其中LeftIsThread 和?RightIsThread 是指當前Left和Right是否為空

public class ThreadedNode<T>
{public T Data { get; set; }public ThreadedNode<T> Left { get; set; }public ThreadedNode<T> Right { get; set; }// 標志位:false表示指向子節點,true表示線索public bool LeftIsThread { get; set; }public bool RightIsThread { get; set; }public ThreadedNode(T data){this.Data = data;this.Left = null;this.Right = null;this.LeftIsThread = false;this.RightIsThread = false;}
}

5.2 線索化構建樹?

public class ThreadedBinaryTree<T>
{private ThreadedNode<T> _root;private ThreadedNode<T> _pre; // 記錄前驅節點// 線索化核心邏輯(中序)private void ThreadNodes(ThreadedNode<T> node){if (node == null) return;// 遞歸線索化左子樹ThreadNodes(node.Left);// 處理當前節點的前驅if (node.Left == null){node.Left = _pre;node.LeftIsThread = true; // 標記為線索}// 處理前驅節點的后繼if (_pre != null && _pre.Right == null){_pre.Right = node;_pre.RightIsThread = true;}_pre = node; // 更新前驅// 遞歸線索化右子樹ThreadNodes(node.Right);}public void BuildThreadedTree(ThreadedNode<T> root){_root = root;_pre = null;ThreadNodes(root);}}

5.3 線索化后中序遍歷方法舉例

// 中序遍歷(利用線索)public void InOrderTraversal(){ThreadedNode<T> current = _root;while (current != null){// 找到最左節點while (!current.LeftIsThread){current = current.Left;}Console.Write(current.Data + " ");// 根據后繼線索遍歷while (current.RightIsThread){current = current.Right;Console.Write(current.Data + " ");}current = current.Right;}

? ?關于紅黑樹和b+樹 下一篇數據結構 樹篇 將會做出徹底詳解?

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

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

相關文章

《Cookie Cutter》中2000多張精靈表與10000個2D光源的管理之道

一個小團隊如何在多個平臺上以優秀的效果展示手繪動畫&#xff1f;Subcult Joint 工作室給出了答案。他們用六年時間開發出了游戲《Cookie Cutter》。游戲中使用了數千個使用傳統動畫技術制作的高分辨率資產&#xff0c;而且這些資產都在 Unity 中進行了優化。由于工作室需要在…

什么是實景VR?實景VR應用場景

實景VR&#xff0c;即基于真實場景的虛擬現實技術&#xff0c;是利用計算機技術生成三維環境&#xff0c;以模擬并再現真實世界場景的技術。 用戶通過佩戴VR設備&#xff08;如VR頭盔、手柄等&#xff09;或通過電腦設備&#xff0c;可以沉浸在一個高度仿真的虛擬環境中&#…

內核性能測試(60s不丟包性能)

以xGAP-200-SE7K-L&#xff08;雙口10G&#xff09;在飛騰D2000上為例&#xff08;單通道最高性能約2.8Gbps) 單口測試 0口&#xff1a; tcp&#xff1a; taskset -c 4 iperf -c 1.1.1.1 -i 1 -t 60 -p 60001 taskset -c 4 iperf -s -i 1 -p 60001 udp&#xff1a; taskse…

58. 區間和

題目鏈接&#xff1a; 58. 區間和 題目描述&#xff1a; 給定一個整數數組 Array&#xff0c;請計算該數組在每個指定區間內元素的總和。 輸入描述 第一行輸入為整數數組 Array 的長度 n&#xff0c;接下來 n 行&#xff0c;每行一個整數&#xff0c;表示數組的元素。隨后…

C#進階(2)stack(棧)

前言 我們前面介紹了ArrayList,今天就介紹另一種數據結構——棧。 這是棧的基本形式,博主簡單畫了一下,你看個意思就行,很明顯,這種數據有一種特征:先進后出。因為先進來的數據會在下面,下面是密閉的,所以只能取后面進來的。 C#為我們封好了這種數據結構,我們不用擔…

汽車工廠數字孿生實時監控技術從數據采集到三維驅動實現

在工業智能制造推動下&#xff0c;數字孿生技術正成為制造業數字化轉型的核心驅動力。今天詳細介紹數字孿生實時監控技術在汽車工廠中的應用&#xff0c;重點解析從數據采集到三維驅動實現的全流程技術架構&#xff0c;并展示其在提升生產效率、降低成本和優化決策方面的顯著價…

git|gitee倉庫同步到github

參考&#xff1a;一次提交更新兩個倉庫&#xff0c;Get 更優雅的 GitHub/Gitee 倉庫鏡像同步 文章目錄 進入需要使用鏡像功能的倉庫&#xff0c;進入「管理」找到「倉庫鏡像管理」選項&#xff0c;點擊「添加鏡像」按鈕綁定github綁定成功后再次點擊添加鏡像如何申請 GitHub 私…

原生小程序+springboot+vue+協同過濾算法的音樂推薦系統(源碼+論文+講解+安裝+部署+調試)

感興趣的可以先收藏起來&#xff0c;還有大家在畢設選題&#xff0c;項目以及論文編寫等相關問題都可以給我留言咨詢&#xff0c;我會一一回復&#xff0c;希望幫助更多的人。 系統背景 在數字音樂產業迅猛發展的當下&#xff0c;Spotify、QQ 音樂、網易云音樂等音樂平臺的曲…

RustDesk

配置中繼服務器 https://rustdesk.com/docs/zh-cn/self-host/windows/ 服務器端 下載Windows版本 rustdesk-server-windows-x86_64.zip&#xff0c;安裝路徑為&#xff1a;C:\Program Files\RustDeskServer\bin。執行 hbbr.exe 和 hbbs.exe 兩個應用程序。這兩個應用提供了兩…

django中用 InforSuite RDS 替代memcache

在 Django 項目中&#xff0c;InforSuite RDS&#xff08;關系型數據庫服務&#xff09;無法直接替代 Memcached&#xff0c;因為兩者的設計目標和功能定位完全不同&#xff1a; 特性MemcachedInforSuite RDS核心用途高性能內存緩存&#xff0c;臨時存儲鍵值對數據持久化關系型…

leetcode 57. Insert Interval

題目描述 代碼&#xff1a;由于intervals已經按照左端點排序&#xff0c;并且intervals中的區間全部不重疊&#xff0c;那么可以斷定intervals中所有區間的右端點也已經是有序的。先二分查找intervals中第一個其右端點>newInterval左端點的區間。然后按照類似于56. Merge In…

去年開發一款鴻蒙Next Os的window工具箱

持拖載多個鴻蒙應用 批量簽名安裝 運行 http://dl.lozn.top/lozn/HarmonySignAndFileManagerTool_2024-11-26.zip 同類型安卓工具箱以及其他軟件下載地址匯總 http://dl.lozn.top/lozn/ 怎么個玩法呢&#xff0c;比如要啟動某app, 拖載識別到包名 點啟動他能主動讀取包名 然后…

Trivy:讓你時刻掌控的開源安全掃描器

深入了解 Trivy:全面的安全掃描工具 在如今互聯網快速發展的時代,軟件的安全性顯得尤為重要。隨著應用程序的復雜性增加,其可能帶來的安全漏洞也在不斷增多。如何快速、準確地發現這些潛在威脅是每個開發者和運維人員心中的課題。今天,我們將為大家介紹一個開源的安全掃描…

網址為 http://xxx:xxxx/的網頁可能暫時無法連接,或者它已永久性地移動到了新網址

這是由于瀏覽器默認的非安全端口所導致的&#xff0c;所謂非安全端口&#xff0c;就是瀏覽器出于安全問題&#xff0c;會禁止一些網絡瀏覽向外的端口。 避免使用6000,6666這樣的端口 6000-7000有很多都不行&#xff0c;所以盡量避免使用這個區間 還有在云服務器中&#xff0c…

Jenkins 執行器(Executor)如何調整限制?

目錄 現象原因解決 現象 Jenkins 構建時&#xff0c;提示如下&#xff1a; 此刻的心情正如上圖中的小老頭&#xff0c;火冒三丈&#xff0c;但是不要急&#xff0c;因為每一次錯誤&#xff0c;都是系統中某個環節在說‘我撐不住了’。 原因 其實是上圖的提示表示 Jenkins 當…

運維實施31-NFS服務

NFS概述 NFS&#xff08;Network File System&#xff09;網絡文件系統&#xff0c;主要用于Linux系統上實現文件共享的一種協議&#xff0c;其客戶端主要是Linux。 沒有用戶認證機制&#xff0c;且數據在網絡上傳送的時候是明文傳送&#xff0c;一般只能在局域網中使用支持多…

藍牙協議架構與調試工具詳解(含 BLE、HCI 命令、調試命令)

本文介紹藍牙協議從物理層到應用層的完整通信流程&#xff0c;并詳解了 Linux 下主流藍牙調試工具的使用方法&#xff0c;適用于嵌入式藍牙驅動開發、BLE調試、通信協議分析等場景。 &#x1f527; 1. 藍牙架構概覽 ? 芯片架構 單模芯片&#xff1a;僅支持 BLE 或 Classic 藍…

激光雷達定位算法在FPGA中的實現——section3 Matlab實現和校驗

1、校驗section2的計算方法是否正確 以section1里面的圖示 舉個例子: 1.1 手動計算 可以計算出4*4方陣C相關參數: 可以計算出余子式矩陣C_1相關參數:

數據結構(2)線性表-順序表

知道一個算法的好壞怎么去判斷以后&#xff0c;就該正式的去學習一些常見的數據結構&#xff0c;當然&#xff0c;這里的數據結構僅僅是初階&#xff0c;不會挨個一個一個學完&#xff0c;后期慢慢來。 一、數據結構總論 一般按照邏輯結構和存儲結構來分類&#xff0c;在初階…

性能測試詳解

&#x1f345; 點擊文末小卡片&#xff0c;免費獲取軟件測試全套資料&#xff0c;資料在手&#xff0c;漲薪更快 一、什么是性能測試 先看下百度百科對它的定義 性能測試是通過自動化的測試工具模擬多種正常、峰值以及異常負載條件來對系統的各項性能指標進行測試 我們可以認為…