2020 注定是多災多難的一年,疫情尚未完全散去,不少大廠已經開始了瘋狂挖人,於是筆者難耐寂寞向某一線網際網路大廠投了乙份簡歷,開始了**之旅。。。。
於是筆者在乙個寂靜的夜晚痛定思痛,總結資料結構面試相關的文章,希望能幫助各位讀者以後面試百戰百勝,對面試官進行絕地反擊,吊打問你的面試者,讓一同面試的同僚瞠目結舌,瘋狂收割大廠offer!
好了, 廢話不多說,開始惡補二叉排序樹的相關知識。
1.1 先看乙個需求
給你乙個數列 (7, 3, 10, 12, 5, 1, 9),要求能夠高效的完成對資料的查詢和新增1.2 解決方案分析
使用陣列
使用鏈式儲存-鍊錶
不管鍊錶是否有序,查詢速度都慢,新增資料速度比陣列快,不需要資料整體移動。
使用二叉排序樹
1.3 二叉排序樹介紹
二叉排序樹:bst: (binary sort(search) tree), 對於二叉排序樹的任何乙個非葉子節點,要求左子節點的值比當前節點的值小,右子節點的值比當前節點的值大。
特別說明:如果有相同的值,可以將該節點放在左子節點或右子節點
比如針對前面的資料 (7, 3, 10, 12, 5, 1, 9) ,對應的二叉排序樹為:
1.4 二叉排序樹建立和遍歷
乙個陣列建立成對應的二叉排序樹,並使用中序遍歷二叉排序樹,比如: 陣列為 array(7, 3, 10, 12, 5, 1, 9) , 建立成對應的二叉排序樹為 :
**實現如下:
public class binarysorttreedemo ;
binarysorttree binarysorttree = new binarysorttree();
// 迴圈新增結點到二叉排序樹
for (int i = 0; i < arr.length; i++)
// 中序遍歷
system.out.println("中序遍歷二叉排序樹");
binarysorttree.infixorder(); }}
// 建立二叉排序樹
class binarysorttree else
} // 中序遍歷
public void infixorder() else }}
// 建立node結點
class node
@override
public string tostring()
// 新增結點的方法
// 遞迴的方式新增結點需要滿足二叉排序樹的要求
public void add(node node)
// 判斷傳入的結點的值和當前子樹根結點的值關係
if (node.value < this.value) else
} else else
} }// 中序遍歷
public void infixorder()
system.out.println(this);
if (this.right != null)
}}
1.5 二叉排序樹的刪除
二叉排序樹的刪除情況比較複雜,有下面三種情況需要考慮
刪除葉子節點 (比如:2, 5, 9, 12)
刪除只有一顆子樹的節點 (比如:1)
刪除有兩顆子樹的節點. (比如:7, 3,10 )
對刪除結點的各種情況的思路分析:
第二種情況: 刪除只有一顆子樹的節點 比如 1
(6) 如果 targetnode 有右子結點
情況三 : 刪除有兩顆子樹的節點. (比如:7, 3,10 )
**實現如下:
package com.mylove.binarysorttree;
public class binarysorttreedemo ;
binarysorttree binarysorttree = new binarysorttree();
// 迴圈新增結點到二叉排序樹
for (int i = 0; i < arr.length; i++)
// 中序遍歷
system.out.println("中序遍歷二叉排序樹");
binarysorttree.infixorder();
binarysorttree.delnode(2);
binarysorttree.delnode(10);
binarysorttree.delnode(1);
system.out.println("~~~~中序遍歷二叉排序樹~~~");
binarysorttree.infixorder(); }}
// 建立二叉排序樹
class binarysorttree else
} // 中序遍歷
public void infixorder() else
} // 查詢要刪除的結點
public node search(int value) else
} // 查詢父結點
public node searchparent(int value) else
} /**
* * @param node
* 傳入的結點(當做二叉排序樹的根節點)
* @return 返回的以node為根結點的二叉排序的最小結點
*/public int delrighttreemin(node node)
// 這時target指向最小結點
// 刪除最小結點
delnode(target.value);
return target.value;
} // 刪除結點
public void delnode(int value) else
// 如果這顆二叉排序樹只有乙個結點
if (root.left == null && root.right == null)
// 查詢targetnode的父結點
node parent = searchparent(value);
// 如果要刪除的結點是葉子結點
if (targetnode.left == null && targetnode.right == null) else if (parent.right != null && parent.right.value == value)
} else if (targetnode.left != null && targetnode.right != null) else else
} else
} else else
} else }}
} }}// 建立node結點
class node
@override
public string tostring()
/***
* @param value
* 希望刪除的結點的值
* @return 如果找到返回該結點否則返回null
*/public node search(int value) else if (value < this.value)
return this.left.search(value);
} else
return this.right.search(value);
} }// 新增結點的方法
// 遞迴的方式新增結點需要滿足二叉排序樹的要求
public void add(node node)
// 判斷傳入的結點的值和當前子樹根結點的值關係
if (node.value < this.value) else
} else else
} }/**
* * @param value
* 要刪除的結點的值
* @return 返回要刪除的結點的父結點,如果沒有返回null
*/public node searchparent(int value) else else if (value >= this.value && this.right != null) else
} }// 中序遍歷
public void infixorder()
system.out.println(this);
if (this.right != null)
}}
二叉排序樹
在複習資料結構,把這個東西總結一下。這種結構是動態查詢表,這種動態是相對靜態查詢 順序查詢,折半查詢,分塊查詢等 來說的。對於各種靜態鍊錶,要達到查詢複雜度為o logn 必須要求有序 而要使插入刪除複雜度為o 1 必須是鍊錶儲存。動態查詢表就可以同時滿足這兩者。動態查詢表的特點是表結構本身在查詢過...
二叉排序樹
name 二叉排序樹相關操作 author unimen date 2011 10 8 13 14 21 刪除結點比較麻煩,總結如下 4大種情況 1 結點p無右孩子 將該點的左孩子變為其在雙親中的同位孩子 1 p為其雙親的左孩子時將其的左孩子變為雙親的左孩子 2 p為其雙親的右孩子時將其的左孩子變為...
二叉排序樹
include include include include struct tree node void insert node struct tree node int void pre order struct tree node void in order struct tree node ...