日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當(dāng)前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

二叉树为空意味着二叉树_不怕面试被问了!二叉树算法大盘点

發(fā)布時間:2025/3/12 编程问答 17 豆豆
生活随笔 收集整理的這篇文章主要介紹了 二叉树为空意味着二叉树_不怕面试被问了!二叉树算法大盘点 小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個參考.

作者 | BoCong-Deng

題圖 | 視覺中國

出品 | CSDN博客

樹結(jié)構(gòu)對于程序員來說應(yīng)該不陌生,特別是二叉樹,基本只要接觸算法這一類的都一定會碰到的,所以我打算通過一篇文章,對二叉樹結(jié)構(gòu)的相關(guān)算法進(jìn)行總結(jié)匯總,思路和代碼實現(xiàn)相結(jié)合,讓你不在懼怕二叉樹。(ps:后面我還想寫一篇樹結(jié)構(gòu)的高級篇,就是多叉數(shù),就是對我平時看算法論文碰到的一些新奇的算法,比如B樹、B+樹,還有我一種叫做Bed樹的新奇算法等等)

單純就是想分享技術(shù)博文,還想說一句就是,如果覺得有用,請點個關(guān)注、給個贊吧,也算對我來說是個寬慰,畢竟也得掉不少頭發(fā),嘿嘿嘿。

下面的思路講解中,我會給出一個類偽代碼的思路,然后進(jìn)行相關(guān)說明,也就是一種思路框架,有了思路框架,以后碰到問題就直接交給框架完成。本文主要說一下二叉搜索樹(Binary Search Tree,簡稱 BST),BST是一種很常用的的二叉樹。它的定義是:一個二叉樹中,任意節(jié)點的值要大于等于左子樹所有節(jié)點的值,且要小于等于右邊子樹的所有節(jié)點的值。如下就是一個符合定義的 BST:

后面如果遇到特殊的思路結(jié)構(gòu),如多叉樹,我會特別說明。首先我們先給出二叉樹的節(jié)點定義(這個定義應(yīng)該不陌生吧,有刷算法題都會碰到)。

public class TreeNode {

int val;

TreeNode left;

TreeNode right;

TreeNode(int x) { val = x; }

}

遞歸

不過這里要說明一點的是,在偽代碼中的“進(jìn)行想要的操作”的位置,不一定就在我放置的位置,具體位置還需要我們根據(jù)不同的實際需求進(jìn)行判斷。不過因為前中后序的遍歷,遞歸進(jìn)入的時機(jī)應(yīng)該需要和我的一樣。

先序遍歷

遍歷根節(jié)點,如果根節(jié)點為空,返回;否則,遍歷根節(jié)點,然后先序遍歷左子樹,再先序遍歷右子樹。

public void preorderTraverse(TreeNode root){
System.out.print(node.val+" ");
preorderTraverse(root.left);
preorderTraverse(root.right);
}

中序遍歷

路過根節(jié)點,如果根節(jié)點為空,返回;否則,中序遍歷左子樹,然后遍歷根節(jié)點,再中序遍歷右子樹。

public void inorderTraverse(TreeNode root){
inorderTraverse(root.left);
System.out.print(node.val+" ");
inorderTraverse(root.right);
}

后序遍歷

路過根節(jié)點,如果根節(jié)點為空,返回;否則,后序遍歷左子樹,再后序遍歷右子樹,最后遍歷根節(jié)點。

public void postorderTraverse(TreeNode root){
postorderTraverse(root.left);
postorderTraverse(root.right);
System.out.print(node.val+" ");
}

迭代(非遞歸)

我們使用迭代的思想,其實就是利用循環(huán)和棧來模擬遞歸的操作,上面遞歸的操作,其實就是一個不斷將自己以及左右子節(jié)點進(jìn)行壓棧和出棧的過程,如果理解了上面的算法下面的算法就好理解了

前序遍歷

public List preorderTraversal(TreeNode root) {
List list = new ArrayList<>;
if(root==){
return list;
}
Stack stack = new Stack<>;
stack.push(root);
while(!stack.isEmpty){
TreeNode res = stack.pop;
if(res.right != )
stack.push(res.right);
if(res.left != )
stack.push(res.left);
list.add(res.val);
}
return list;
}

中序遍歷

public List inorderTraversal(TreeNode root) {
List list = new ArrayList<>;
if(root==){
return list;
}
Stack stack = new Stack<>;
TreeNode curr = root;
while(curr != || !(stack.isEmpty)){
if(curr!= ){
stack.push(curr);
curr = curr.left;
}else{
curr = stack.pop;
list.add(curr.val);
curr = curr.right;
}
}
return list;
}

后序遍歷

我們可以很簡單的實現(xiàn)另一種遍歷:”根->右->左“遍歷。雖然這種遍歷沒有名字,但是他是后序遍歷的反序。所以我們可以利用兩個棧,利用棧的LIFO特點,來實現(xiàn)后續(xù)遍歷。

public List preorderTraversal(TreeNode root) {
List list = new ArrayList<>;
if(root==){
return list;
}
Stack stack = new Stack<>;
stack.push(root);
while(!stack.isEmpty){
TreeNode res = stack.pop;
if(res.left != )
stack.push(res.left);
if(res.right != )
stack.push(res.right);
list.add(res.val);
}
list.reserve;
return list;
}

深度優(yōu)先搜索(DFS)

其實,二叉樹的先序遍歷,中序遍歷,后序遍歷,都是深度優(yōu)先搜索,深搜是一種思想,并不具體指代實現(xiàn)方式,你可以使用遞歸,也可以使用棧來實現(xiàn),所以上面提到的都是深度優(yōu)先搜索的實現(xiàn)方式,畢竟“深度優(yōu)先”嘛。

那在這里我就是提幾個實際的應(yīng)用的例子,加深一下印象。

二叉樹的最大深度

public int maxDepth(TreeNode root) {
if(root==){
return 0;
}
int left = maxDepth(root.left);
int right = maxDepth(root.right);
return Math.max(left,right)+1;
}

二叉樹的鏡像

public void Mirror(TreeNode root) {
if(root!=){
if(root.left!= || root.right!= ){
TreeNode temp =root.left;
root.left=root.right;
root.right=temp;
}
Mirror(root.left);
Mirror(root.right);
}
}

對稱二叉樹

boolean isSymmetrical(TreeNode pRoot){
if(pRoot == )
return true;
return real(pRoot.left,pRoot.right);
}
public boolean real(TreeNode root1,TreeNode root2){
if(root1 == && root2 == ){
return true;
}
if(root1 == || root2 == ){
return false;
}
if(root1.val != root2.val){
return false;
}
return real(root1.left,root2.right)&&real(root1.right,root2.left);
}

路徑總和

public class Solution {
private ArrayList list = new ArrayList;
private ArrayList> listAll = new ArrayList>;
public ArrayList> FindPath(TreeNode root,int target) {
if(root == )
return listAll;
list.add(root.val);
target -= root.val;
if(target == 0 && root.left== && root.right == ){
listAll.add(new ArrayList(list));
}
FindPath(root.left,target);
FindPath(root.right,target);
list.remove(list.size-1);
return listAll;
}
}

重建二叉樹

public TreeNode reConstructBinaryTree(int [] pre,int [] in) {
return reConstructBinaryTree(pre,0,pre.length-1,in,0,in.length-1);
}
public TreeNode reConstructBinaryTree(int [] pre,int startpre,int endpre,int [] in,int startin,int endin){
if(startpre > endpre || startin > endin){
return ;
}
TreeNode root = new TreeNode(pre[startpre]);
for(int i =startin;i<=endin;i++){
if(in[i] == pre[startpre]){
root.left = reConstructBinaryTree(pre,startpre+1,startpre+i-startin,in,startin,i-1);
root.right = reConstructBinaryTree(pre,startpre+i-startin+1,endpre,in,i+1,endin);
}
}
return root;
}

二叉搜索樹的最近公共祖先

class Solution {
public TreeNode lowestCommonAncestor(TreeNode root, TreeNode p, TreeNode q) {
if(root == || root == p || root == q){
return root;
}
TreeNode left = lowestCommonAncestor(root.left,p,q);
TreeNode right = lowestCommonAncestor(root.right,p,q);
if(left!= && right!=){
return root;
}
return left!=?left:right;
}
}

二叉樹的序列化和反序列化

序列化:
public String serialize(TreeNode root) {
if (root == ) {
return ;
}
// 利用二叉樹的層次遍歷方式進(jìn)行序列化
StringBuilder res = new StringBuilder;
LinkedList queue = new LinkedList<>;
queue.add(root);
while (!queue.isEmpty) {
TreeNode node = queue.remove;
if (node != ) {
res.append(node.val).append(

總結(jié)

以上是生活随笔為你收集整理的二叉树为空意味着二叉树_不怕面试被问了!二叉树算法大盘点的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網(wǎng)站內(nèi)容還不錯,歡迎將生活随笔推薦給好友。