數據結構筆記--二叉樹經典高頻題

1--二叉樹的最近公共祖先

主要思路:

? ? ? ? 最近祖先只有兩種情況:① 自底向上,當兩個目的結點分別在當前結點的左右子樹時,當前結點為兩個目的結點的最近祖先;② 最近祖先與其中一個目的結點相同,則另一個目的結點在目的結點的子樹上;

? ? ? ? 遞歸尋找目的結點,當找到目的結點后往上返回目的結點,否則返回 NULL;當一個結點在左右子樹上分別找到了兩個目的結點,表明這個結點是最近祖先;否則返回不為空的子樹的返回結點(這時兩個結點對應第 ② 種情況);

#include <iostream>
#include <vector>
#include <stack>struct TreeNode {int val;TreeNode *left;TreeNode *right;TreeNode(int x) : val(x), left(NULL), right(NULL) {}
};class Solution {
public:TreeNode* lowestCommonAncestor(TreeNode* root, TreeNode* p, TreeNode* q) {if(root == NULL || root->val == p->val || root->val == q->val) return root;TreeNode* left = lowestCommonAncestor(root->left, p, q);TreeNode* right = lowestCommonAncestor(root->right, p, q);if(left != NULL && right != NULL) return root;else if( left != NULL) return left;else return right;}
};int main(int argc, char *argv[]){TreeNode *Node1 = new TreeNode(3);TreeNode *Node2 = new TreeNode(5);TreeNode *Node3 = new TreeNode(1);TreeNode *Node4 = new TreeNode(6);TreeNode *Node5 = new TreeNode(2);TreeNode *Node6 = new TreeNode(0);TreeNode *Node7 = new TreeNode(8);TreeNode *Node8 = new TreeNode(7);TreeNode *Node9 = new TreeNode(4);Node1->left = Node2;Node1->right = Node3;Node2->left = Node4;Node2->right = Node5;Node3->left = Node6;Node3->right = Node7;Node5->left = Node8;Node6->right = Node9;Solution S1;TreeNode* res = S1.lowestCommonAncestor(Node1, Node2, Node9);std::cout << res->val << std::endl;return 0;
}

2--二叉搜索樹的中序后繼結點

主要思路:

? ? ? ? 如果 p 結點有右子樹,則返回其右子樹最左邊的結點(中序遍歷的定義);

? ? ? ? 如果 p 結點沒有右子樹,則從 root 結點開始尋找 p 結點的父親結點;(根據二叉搜索樹的定義,可以節省尋找的時間,只需在一邊進行尋找);

#include <iostream>
#include <vector>
#include <stack>struct TreeNode {int val;TreeNode *left;TreeNode *right;TreeNode(int x) : val(x), left(NULL), right(NULL) {}
};class Solution {
public:TreeNode* inorderSuccessor(TreeNode* root, TreeNode* p) {TreeNode *res = NULL;if(p->right != NULL){ // p的中序后繼是其右子樹上最左的結點(即右字數上最先返回的結點)res = p->right;while(res->left != NULL) res = res->left;return res;}// p沒有右子樹,從root結點開始搜索p的父親結點while(root != NULL){if(root->val > p->val){ // p在左子樹上res = root;root = root->left; // 在左子樹上找到最后一個比p大的結點(中序遍歷是有序的,中序后繼結點表明是比p結點大)}else{root = root->right; // p在右子樹上}}return res;}
};int main(int argc, char *argv[]){TreeNode *Node1 = new TreeNode(2);TreeNode *Node2 = new TreeNode(1);TreeNode *Node3 = new TreeNode(3);Node1->left = Node2;Node1->right = Node3;Solution S1;TreeNode* res = S1.inorderSuccessor(Node1, Node2);std::cout << res->val << std::endl;return 0;
}

3--二叉樹的序列化與反序列化

主要思路:

? ? ? ? 利用前序遍歷或層次遍歷等方式進行序列化,再根據不同遍歷的方式來設計反序列化的方式,利用反序列化重構二叉樹;

? ? ? ? 下面的代碼使用了層次遍歷進行序列化,并通過類似層次遍歷的方式進行反序列化重構二叉樹;

#include <iostream>
#include <string>
#include <vector>
#include <queue>struct TreeNode {int val;TreeNode *left;TreeNode *right;TreeNode(int x) : val(x), left(NULL), right(NULL) {}
};class Codec {
public:std::string serialize(TreeNode* root) {std::string res = "";if (root == NULL) return res;std::queue<TreeNode*> q;q.push(root);res += std::to_string(root->val) + ",";while(!q.empty()){TreeNode* tmp = q.front();q.pop();if(tmp->left != NULL){q.push(tmp->left);res += std::to_string(tmp->left->val) + ",";}else res += "#,";if(tmp->right != NULL){q.push(tmp->right);res += std::to_string(tmp->right->val) + ",";}else res += "#,";}return res;}TreeNode* deserialize(std::string data) {if (data.length() == 0) return NULL;std::vector<std::string> value;for(auto i = 0; i < data.length(); i++){std::string tmp = "";while(data[i] != ','){tmp += data[i];i++;}value.push_back(tmp);}TreeNode *res = new TreeNode(std::stoi(value[0]));std::queue<TreeNode*> q;q.push(res);int idx = 1;while(!q.empty()){TreeNode* tmp = q.front();q.pop();if(value[idx] != "#"){ // 左兒子tmp->left = new TreeNode(std::stoi(value[idx]));q.push(tmp->left);} idx++;if(value[idx] != "#"){ // 右兒子tmp->right = new TreeNode(std::stoi(value[idx]));q.push(tmp->right);} idx++;}return res;}
};void printTreeNode(TreeNode *root){if (root == NULL) return;std::queue<TreeNode*> q;q.push(root);std::cout << root->val << " ";while(!q.empty()){TreeNode* tmp = q.front();q.pop();if(tmp->left != NULL){q.push(tmp->left);std::cout << tmp->left->val << " ";}else std::cout << "null" << " ";if(tmp->right != NULL){q.push(tmp->right);std::cout << tmp->right->val << " ";}else std::cout << "null" << " ";}
}int main(int argc, char *argv[]){//root = [1,2,3,null,null,4,5]TreeNode *Node1 = new TreeNode(1);TreeNode *Node2 = new TreeNode(2);TreeNode *Node3 = new TreeNode(3);TreeNode *Node4 = new TreeNode(4);TreeNode *Node5 = new TreeNode(5);Node1->left = Node2;Node1->right = Node3;Node3->left = Node4;Node3->right = Node5;Codec S1;std::cout << S1.serialize(Node1) << std::endl;TreeNode *res = S1.deserialize(S1.serialize(Node1));printTreeNode(res);return 0;
}

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

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

相關文章

Python-OpenCV中的圖像處理-形態學轉換

Python-OpenCV中的圖像處理-形態學轉換 形態學轉換腐蝕膨脹開運算閉運算形態學梯度禮帽黑帽形態學操作之間的關系 形態學代碼例程 形態學轉換 形態學操作:腐蝕&#xff0c;膨脹&#xff0c;開運算&#xff0c;閉運算&#xff0c;形態學梯度&#xff0c;禮帽&#xff0c;黑帽等…

企業微信 企業內部開發 學習筆記

官方文檔 文檔 術語介紹 引入pom <dependency><groupId>com.github.binarywang</groupId><artifactId>wx-java-cp-spring-boot-starter</artifactId><version>4.5.3.B</version></dependency>核心代碼 推送消息 final WxCp…

面試攻略,Java 基礎面試 100 問(十一)

抽象類&#xff08;abstract class&#xff09;和接口&#xff08;interface&#xff09;有什么異同? 抽象類和接口都不能夠實例化&#xff0c;但可以定義抽象類和接口類型的引用。一個類如果繼承了某個抽象類或者實現了某個接口都需要對其中的抽象方法全部進行實現&#xff…

SpringBoot 后端項目利用 Minio 實現分片上傳、斷點續傳

一、準備工作 安裝 Minio 服務后&#xff0c;在 SpringBoot 項目中添加依賴&#xff1a; <!-- MinIO --><dependency><groupId>io.minio</groupId><artifactId>minio</artifactId><version>8.2.1</version></dependency&g…

【js】日期、時間正則匹配

1、日期的正則表達式 格式&#xff1a;2023-08-11 var reg /^[1-9]\d{3}-(0[1-9]|1[0-2])-(0[1-9]|[1-2][0-9]|3[0-1])$/; var regExp new RegExp(reg); if(!regExp.test(value)){alert("日期格式不正確");return; }2、時間的正則表達式 格式&#xff1a;23:00:00…

英碼國產高配邊緣計算盒子上市!搭載TPU處理器BM1684X,適配麒麟系統,支持OTA升級!

隨著人工智能技術不斷深入實際應用場景&#xff0c;加速各行各業場景應用落地&#xff0c;邊緣計算的重要性越發凸顯。相較于傳統的集中式云計算&#xff0c;邊緣計算在距離數據源或用戶更近的地方提供計算能力&#xff0c;不僅滿足了對實時性要求較高的場景應用需求&#xff0…

操作系統結構

操作系統結構 分層法模塊化宏內核微內核微內核的基本概念微內核的基本功能 內核 分層法 分層法是將操作系統分為若干層&#xff0c;最底層為硬件&#xff0c;最高層為用戶接口&#xff0c;每層只能調用緊鄰它的底層的功能和服務&#xff08;單向依賴&#xff09; 分層法的優點…

如何通過CSS選擇器選擇一個元素的子元素?如何選擇第一個子元素和最后一個子元素?

聚沙成塔每天進步一點點 ? 專欄簡介? 選擇一個元素的子元素? 選擇第一個子元素和最后一個子元素? 注意事項? 寫在最后 ? 專欄簡介 前端入門之旅&#xff1a;探索Web開發的奇妙世界 記得點擊上方或者右側鏈接訂閱本專欄哦 幾何帶你啟航前端之旅 歡迎來到前端入門之旅&…

線程池,以及線程池的實現以及面試常問的問題,工廠模式,常見的鎖策略(面試常考,要了解,不行就背)

一、&#x1f49b; 線程池的基本介紹 內存池&#xff0c;進程池&#xff0c;連接池&#xff0c;常量池&#xff0c;這些池子概念上都是一樣的&#xff5e;&#xff5e; 如果我們需要頻繁的創建銷毀線程&#xff0c;此時創建銷毀的成本就不能忽視了&#xff0c;因此就可以使用線…

Java中使用instanceof判斷對象類型

記錄&#xff1a;470 場景&#xff1a;Java中使用instanceof判斷對象類型。例如在解析JSON字符串轉換為指定類型時&#xff0c;先判斷類型&#xff0c;再定向轉換。在List<Object>中遍歷Object時&#xff0c;先判斷類型&#xff0c;再定向轉換。 版本&#xff1a;JDK 1…

Redis系列(一):深入了解Redis數據類型和底層數據結構

Redis有以下幾種常用的數據類型&#xff1a; redis數據是如何組織的 為了實現從鍵到值的快速訪問&#xff0c;Redis 使用了一個哈希表來保存所有鍵值對。 Redis全局哈希表&#xff08;Global Hash Table&#xff09;是指在Redis數據庫內部用于存儲所有鍵值對的主要數據結構。…

安卓13不再支持PPTP怎么辦?新的連接解決方案分享

隨著Android 13的發布&#xff0c;我們迎來了一個令人興奮的新品時刻。然而&#xff0c;對于一些用戶而言&#xff0c;這也意味著必須面對一個重要的問題&#xff1a;Android 13不再支持PPTP協議。如果你是一個習慣使用PPTP協議來連接換地址的用戶&#xff0c;那么你可能需要重…

C++ 泛型編程:函數模板

文章目錄 前言一、什么是泛型編程二、函數模板三、函數模板的使用四、多參數函數模板五&#xff0c;示例代碼&#xff1a;總結 前言 當需要編寫通用的代碼以處理不同類型的數據時&#xff0c;C 中的函數模板是一個很有用的工具。函數模板允許我們編寫一個通用的函數定義&#…

Vue day02 Computed和Watch

1.事件綁定 可以用 v-on 指令監聽DOM 事件&#xff0c;并在觸發時運行一些 JavaScript 代碼。v-on 還可以接收一個需要調用的方法名稱。 <button v-on:click"handler">good</button> methods: { handler: function (event) { if (event) { alert(event.t…

接口測試之Jmeter+Ant+Jenkins接口自動化測試平臺

平臺簡介 一個完整的接口自動化測試平臺需要支持接口的自動執行&#xff0c;自動生成測試報告&#xff0c;以及持續集成。Jmeter支持接口的測試&#xff0c;Ant支持自動構建&#xff0c;而Jenkins支持持續集成&#xff0c;所以三者組合在一起可以構成一個功能完善的接口自動化…

BOLT- 識別和優化熱門的基本塊

在BOLT中&#xff0c;識別和優化熱門的基本塊之所以關鍵&#xff0c;是因為BOLT的主要目標是優化程序以更好地利用硬件特性&#xff0c;特別是指令緩存&#xff08;ICache&#xff09;。以下是BOLT如何識別和優化熱門基本塊的流程&#xff1a; 收集性能數據: BOLT開始的時候并不…

idea - 刷新 Git 分支數據 / 命令刷新 Git 分支數據

一、idea - 刷新 Git 分支數據 idea 找到 fetch 選項&#xff0c;重新獲取分支數據 二、命令刷新 Git 分支數據 git fetch參考鏈接 1. 遠程Gitlab新建的分支在IDEA里不顯示

jxls導出問題

![請添加圖片描述](https://img-blog.csdnimg.cn/bc74c4207818491c93b75e19b3333451.png 為什么最后導出的文件還是按原樣導出啊&#xff0c;沒有填充數據 ![在這里插入圖片描述](https://img-blog.csdnimg.cn/d4500b9a98c042f6b64a5d0650071303.png

qt多線程使用方式

有5個方式&#xff1a;可以參考這個博客&#xff1a;Qt 中開啟線程的五種方式_qt 線程_lucky-billy的博客-CSDN博客 注&#xff1a;為了實現更加靈活的線程管理&#xff08;因為這5種都有一些不方便之處&#xff1a;QThread需要子類化且不能傳參&#xff0c;moveToThread不能傳…

【leetcode】459. 重復的子字符串(easy)

給定一個非空的字符串 s &#xff0c;檢查是否可以通過由它的一個子串重復多次構成。 示例 1: 輸入: s “abab” 輸出: true 解釋: 可由子串 “ab” 重復兩次構成。 示例 2: 輸入: s “aba” 輸出: false 示例 3: 輸入: s “abcabcabcabc” 輸出: true 解釋: 可由子串 “ab…