記事ディレクトリ
二分探索木
1.二分探索木の概念
バイナリソートツリーとも呼ばれるバイナリ検索ツリーは、空のツリー**または次のプロパティを持つバイナリツリーのいずれかです。
- 左側のサブツリーが空でない場合、左側のサブツリー内のすべてのノードの値は、ルートノードの値よりも小さくなります。
- 右側のサブツリーが空でない場合、右側のサブツリー内のすべてのノードの値がルートノードの値よりも大きくなります
- その左右のサブツリーも二分探索木です。
2.二分木操作-検索
コード:
public Node search(int val){
while (root != null){
if(val > root.val){
// val>root.val 在右子树查找
root = root.right;
}else if(val < root.val){
// val<root.val 在左子树查找
root = root.left;
}else {
// val=root.val 返回该节点即可
return root;
}
}
return null;
}
3.二分木操作-挿入
コード:
public boolean insert(int val) {
// 当为空树的时候 直接插入val
if(root == null) {
root = new Node(val);
return true;
}
// 当不为空时的时候,进行判断
Node parent = null;
Node child = root;
while (child != null){
// val 较大 寻找右子树
if(child.val < val){
parent = child;
child = child.right;
}else {
//val 较小 寻找左子树
parent = child;
child = child.left;
}
}
// 这里 parent的左子树或右子树就可以进行插入,此时进行判断.
if(parent.val < val){
parent.right = new Node(val);
}else {
parent.left = new Node(val);
}
return true;
}
4.二分木操作-削除
public void remove(int key) {
Node cur = root;
Node parent = null;
while (cur != null){
if(cur.val == key){
//找到要删除的节点 进行删除
removeNode(cur,parent);
}else if(cur.val < key){
parent = cur;
cur = cur.right;
}else {
parent = cur;
cur = cur.left;
}
}
}
public void removeNode(Node cur,Node parent){
if(cur.left == null){
// 情况一
if(cur == root){
root = cur.right;
}else if(cur == parent.left){
parent.left = cur.right;
}else {
parent.right = cur.right;
}
}else if(cur.right == null){
// 情况二
if(cur == root){
root = cur.left;
}else if(cur == parent.right){
parent.right = cur.left;
}else {
parent.left = cur.left;
}
}else {
// 情况三
Node targetParent = cur;
Node target = cur.right;
while(target.left != null){
targetParent = target;
target = target.left;
}
cur.val = target.val;
if(target == targetParent.left){
targetParent.left = target.right;
}else {
targetParent.right = target.right;
}
}
}
5.パフォーマンス分析
挿入操作と削除操作の両方を最初に検索する必要があります。検索効率は、バイナリ検索ツリーの各操作のパフォーマンスを表します。
n個のノードを持つ二分探索木の場合、各要素を探索する確率が等しい場合、二分探索木の平均探索長は、二分探索木のノードの深さの関数になります。ノードは、より多くの回数です。
しかし、同じキーコードセットに対して、各キーコードの挿入順序が異なる場合、異なる構造の二分探索木を取得することが可能です。
最適な場合、二分探索木は完全な二分木であり、平均比較の数は次のとおりです。
最悪の場合、二分探索木は単一分岐木に縮退し、比較の平均数は次のようになります。