まず、バイナリツリー&
ツリーは、ノードおよびエッジ、記憶素子のセットから構成されています。ルートノードポイント、親と子ノードの概念。
図:ツリー深さ= 4;図5は、ルートノードである; 8の関係図3は、同じ親子関係です。
バイナリバイナリツリーは、その後、「バイナリ」(バイナリ)を追加し、それがツリーに区別するための手段。各サブノードは最大で2(子)、左チャイルド&右の子を持っています。多くの場合、バイナリツリーのようなバイナリツリーの使用は、算術式です。
図:左ノードは1/8であり; 2/3右ノードです。
第二に、二分探索木BST
名前が示すように、バイナリツリーは、制限検索を追加しました。その要件:各ノードは、右サブツリー要素よりも小さい、その左サブツリー要素よりも大きいです。
図:任意のノード内の各ノードは、その左の部分木より大きく、小さいその右サブツリーのいずれよりもノード
次のようにJavaのコードは次のとおりです。
public class BinarySearchTree {
/**
* 根节点
*/
public static TreeNode root;
public BinarySearchTree() {
this.root = null;
}
/**
* 查找
* 树深(N) O(lgN)
* 1\. 从root节点开始
* 2\. 比当前节点值小,则找其左节点
* 3\. 比当前节点值大,则找其右节点
* 4\. 与当前节点值相等,查找到返回TRUE
* 5\. 查找完毕未找到,
* @param key
* @return
*/
public TreeNode search (int key) {
TreeNode current = root;
while (current != null
&& key != current.value) {
if (key < current.value )
current = current.left;
else
current = current.right;
}
return current;
}
/**
* 插入
* 1\. 从root节点开始
* 2\. 如果root为空,root为插入值
* 循环:
* 3\. 如果当前节点值大于插入值,找左节点
* 4\. 如果当前节点值小于插入值,找右节点
* @param key
* @return
*/
public TreeNode insert (int key) {
// 新增节点
TreeNode newNode = new TreeNode(key);
// 当前节点
TreeNode current = root;
// 上个节点
TreeNode parent = null;
// 如果根节点为空
if (current == null) {
root = newNode;
return newNode;
}
while (true) {
parent = current;
if (key < current.value) {
current = current.left;
if (current == null) {
parent.left = newNode;
return newNode;
}
} else {
current = current.right;
if (current == null) {
parent.right = newNode;
return newNode;
}
}
}
}
/**
* 删除节点
* 1.找到删除节点
* 2.如果删除节点左节点为空 , 右节点也为空;
* 3.如果删除节点只有一个子节点 右节点 或者 左节点
* 4.如果删除节点左右子节点都不为空
* @param key
* @return
*/
public TreeNode delete (int key) {
TreeNode parent = root;
TreeNode current = root;
boolean isLeftChild = false;
// 找到删除节点 及 是否在左子树
while (current.value != key) {
parent = current;
if (current.value > key) {
isLeftChild = true;
current = current.left;
} else {
isLeftChild = false;
current = current.right;
}
if (current == null) {
return current;
}
}
// 如果删除节点左节点为空 , 右节点也为空
if (current.left == null && current.right == null) {
if (current == root) {
root = null;
}
// 在左子树
if (isLeftChild == true) {
parent.left = null;
} else {
parent.right = null;
}
}
// 如果删除节点只有一个子节点 右节点 或者 左节点
else if (current.right == null) {
if (current == root) {
root = current.left;
} else if (isLeftChild) {
parent.left = current.left;
} else {
parent.right = current.left;
}
}
else if (current.left == null) {
if (current == root) {
root = current.right;
} else if (isLeftChild) {
parent.left = current.right;
} else {
parent.right = current.right;
}
}
// 如果删除节点左右子节点都不为空
else if (current.left != null && current.right != null) {
// 找到删除节点的后继者
TreeNode successor = getDeleteSuccessor(current);
if (current == root) {
root = successor;
} else if (isLeftChild) {
parent.left = successor;
} else {
parent.right = successor;
}
successor.left = current.left;
}
return current;
}
/**
* 获取删除节点的后继者
* 删除节点的后继者是在其右节点树种最小的节点
* @param deleteNode
* @return
*/
public TreeNode getDeleteSuccessor(TreeNode deleteNode) {
// 后继者
TreeNode successor = null;
TreeNode successorParent = null;
TreeNode current = deleteNode.right;
while (current != null) {
successorParent = successor;
successor = current;
current = current.left;
}
// 检查后继者(不可能有左节点树)是否有右节点树
// 如果它有右节点树,则替换后继者位置,加到后继者父亲节点的左节点.
if (successor != deleteNode.right) {
successorParent.left = successor.right;
successor.right = deleteNode.right;
}
return successor;
}
public void toString(TreeNode root) {
if (root != null) {
toString(root.left);
System.out.print("value = " + root.value + " -> ");
toString(root.right);
}
}
}
/**
* 节点
*/
class TreeNode {
/**
* 节点值
*/
int value;
/**
* 左节点
*/
TreeNode left;
/**
* 右节点
*/
TreeNode right;
public TreeNode(int value) {
this.value = value;
left = null;
right = null;
}
}
ポイントをインタビュー:データ構造のTreeNodeを理解するために
ノードデータ構造、即ち、左ノードとノード点の右ノードとノード自体の値。フィギュア
ポイント2インタビュー:バイナリツリーの最大の深さまたは最小深さを決定する方法
答え:単純な再帰実装することができ、次のように:
int maxDeath(TreeNode node){
if(node==null){
return 0;
}
int left = maxDeath(node.left);
int right = maxDeath(node.right);
return Math.max(left,right) + 1;
}
int getMinDepth(TreeNode root){
if(root == null){
return 0;
}
return getMin(root);
}
int getMin(TreeNode root){
if(root == null){
return Integer.MAX_VALUE;
}
if(root.left == null&&root.right == null){
return 1;
}
return Math.min(getMin(root.left),getMin(root.right)) + 1;
}
ポイント3インタビュー:バイナリツリーは平衡二分木であるかどうかを確認する方法
答え:単純な再帰実装することができ、次のように:
boolean isBalanced(TreeNode node){
return maxDeath2(node)!=-1;
}
int maxDeath2(TreeNode node){
if(node == null){
return 0;
}
int left = maxDeath2(node.left);
int right = maxDeath2(node.right);
if(left==-1||right==-1||Math.abs(left-right)>1){
return -1;
}
return Math.max(left, right) + 1;
}
ポイントバイナリツリーは、面接後のポイントは、バイナリツリーの検索で、面接の前にあります。曹操は、バイナリコードを実行します。
public class BinarySearchTreeTest {
public static void main(String[] args) {
BinarySearchTree b = new BinarySearchTree();
b.insert(3);b.insert(8);b.insert(1);b.insert(4);b.insert(6);
b.insert(2);b.insert(10);b.insert(9);b.insert(20);b.insert(25);
// 打印二叉树
b.toString(b.root);
System.out.println();
// 是否存在节点值10
TreeNode node01 = b.search(10);
System.out.println("是否存在节点值为10 => " + node01.value);
// 是否存在节点值11
TreeNode node02 = b.search(11);
System.out.println("是否存在节点值为11 => " + node02);
// 删除节点8
TreeNode node03 = b.delete(8);
System.out.println("删除节点8 => " + node03.value);
b.toString(b.root);
}
}
結果は以下の通りであります:
value = 1 -> value = 2 -> value = 3 -> value = 4 -> value = 6 -> value = 8 -> value = 9 -> value = 10 -> value = 20 -> value = 25 ->
是否存在节点值为10 => 10
是否存在节点值为11 => null
删除节点8 => 8
value = 1 -> value = 2 -> value = 3 -> value = 4 -> value = 6 -> value = 9 -> value = 10 -> value = 20 -> value = 25 ->
ポイント4インタビュー:バイナリツリーの検索を挿入する方法
挿入して、動的な変更バイナリ検索ツリーにつながる同じを削除します。比較的単純な処理ロジックを穿刺挿入反対。図ロジック挿入:
- ルートノードから始まって
- ルートが空の場合、ルート値に挿入されます
- ループ:
- 値は、現在のノードが左ノードを探し、値が挿入されているよりも大きい場合
- 値は、現在のノードの値が挿入さ未満である場合、右のノードを見つけるために
インタビュー2.5:バイナリツリーの検索を見つける方法
そのアルゴリズムの複雑さ:O(LGN)、ツリーの深さ(N)。図ルックアップ論理:
- ルートノードから始まって
- ノードの現在の値よりも小さく、そして見つけるその左ノード
- 大ノードの現在の値よりも、その右のノードを見つけます
- 現在のノードの値に等しい、trueを返しを見つけます
- 完全な検索が見つかりませんでした
インタビュー2.5:バイナリツリーの検索を削除する方法
より複雑な。まず、方法を探している削除されたノードを、見つける:後続ノードがノードツリー内の右ノードの最小で削除します。図は、対応する論理を削除します。
結果は以下のとおりです。
- 見つかったノードを削除します。
- 左のノードが空の中にノードを削除した場合、右のノードはnullです
- ノードを削除した場合のみ、一人の子供は、左または右ノードノード
- あなたは左と右の子を削除した場合のノードが空ではありません
IIIの概要
人民元効率的なインタビューのプログラムとしてコードと時折、ボウルのように「古い祭壇漬け牛肉麺」の味を食べて、常に種類のは、そのようなBSTなど、言葉で表せないほどの風味をするアルゴリズムを味わいます。