春招某大廠 不會二叉排序樹還想進來?

2021-10-04 03:41:00 字數 4454 閱讀 7195

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 ...