减治法在查找算法中的应用(JAVA)--二叉查找树的查找、插入、删除
生活随笔
收集整理的這篇文章主要介紹了
减治法在查找算法中的应用(JAVA)--二叉查找树的查找、插入、删除
小編覺得挺不錯的,現在分享給大家,幫大家做個參考.
減治法在查找算法中的應用
二叉查找樹的查找與插入:
二叉排序樹或者是一棵空樹,或者是具有下列性質的二叉樹:(1)若左子樹不空,則左子樹上所有結點的值均小于或等于它的根節點的值;
(2)若右子樹不空,則右子樹上所有結點的值均大于或等于它的根結點的值;
(3)左、右子樹也分別為二叉排序樹。
對于二叉查找樹這里我們介紹查找、插入和刪除操作:
這些操作會將問題的規模變成一個更小的二叉樹,也運用到了減治法的思想。
查找思路:如果樹為空,直接返回,查找失敗。反之,將查找值key與根root的值比較,如果相等,則root即為所找;若key < root.v,則繼續在左子樹查找;若key > root.v,則繼續在右子樹查找。
public static Node find(int key) {if (root == null) {System.out.println("The tree is empty!");return null;}Node cur = root;while (cur.v != key) {if (key < cur.v) {cur = cur.l;}else {cur = cur.r;}if (cur == null) {return null;}}return cur;插入思路:基本思想和查找操作類似,如果為空樹,直接返回,插入節點即為根節點;否則,比較根節點的值與插入節點的值。注意用parent記錄遍歷到最后的cur值。
(1)刪除葉子結點。可直接刪除,不會影響其他
(2)刪除結點有且只有一側孩子結點。孩子結點覆蓋待刪除結點,刪除孩子結點
(3)刪除結點下既有左孩子,又有右孩子。在待刪除結點的右孩子下,找到v值最小的,用這個結點覆蓋要刪除的結點。(這里是因為中序遍歷結點的后繼結點一定是在右子樹中v值最小的結點)
public static boolean delete(int key) {Node cur = root;Node parent = root;boolean hasLeft = true;while (cur != null && cur.v != key) {parent = cur;if (key < cur.v) {cur = cur.l;hasLeft = true;} else {cur = cur.r;hasLeft = false;}}if (cur == null) {return false;}if (cur.l == null && cur.r == null) {/*** 要刪除的節點為葉子節點,直接刪除* */if (cur == root) {root = null;}if (hasLeft) {parent.l = null;} else {parent.r = null;}} else if (cur.r == null) {/*** 要刪除的節點只有左孩子* */if (cur == root) {root = cur.l;}if (hasLeft) {parent.l = cur.l;} else {parent.r = cur.l;}} else if (cur.l == null) {/*** 要刪除的節點只有右孩子* */if (cur == root) {root = cur.r;}if (hasLeft) {parent.l = cur.r;}else {parent.r = cur.r;}} else {/*** 要刪除的節點既有左孩子又有右孩子* 思路:用待刪除節點右子樹中的v值最小的結點來替代要刪除的節點,然后刪除右子樹中結點* 右子樹中v值最小的節點一定沒有左子樹,所以刪除的這個結點一定是屬于葉子節點或只有右子樹的節點* */Node directPostNode = getPost(cur);cur.v = directPostNode.v;}return true; } private static Node getPost(Node delNode) {Node parent = delNode;Node dir = delNode;Node cur = delNode.r;while (cur != null) {parent = dir;dir = cur;cur = cur.l;}if (dir != delNode.r) {//從樹中刪除此直接后繼節點parent.l = dir.r;dir.r = null;}return dir; }完整代碼如下: class Node {int v;Node l;Node r;public Node(int v) {this.v = v;} } public class Main {public static Node root;public static Node find(int key) {if (root == null) {System.out.println("The tree is empty!");return null;}Node cur = root;while (cur.v != key) {if (key < cur.v) {cur = cur.l;}else {cur = cur.r;}if (cur == null) {return null;}}return cur;}public static void insert(Node node) {if (root == null) {root = node;return;}Node cur = root;Node parent = root;boolean hasLeft = true;while (cur != null) {parent = cur;if (node.v > cur.v) {cur = cur.r;hasLeft = true;} else {cur = cur.l;hasLeft = false;}}if (hasLeft) {parent.l = node;} else {parent.r = node;}}public static boolean delete(int key) {Node cur = root;Node parent = root;boolean hasLeft = true;while (cur != null && cur.v != key) {parent = cur;if (key < cur.v) {cur = cur.l;hasLeft = true;} else {cur = cur.r;hasLeft = false;}}if (cur == null) {return false;}if (cur.l == null && cur.r == null) {/*** 要刪除的節點為葉子節點,直接刪除* */if (cur == root) {root = null;}if (hasLeft) {parent.l = null;} else {parent.r = null;}} else if (cur.r == null) {/*** 要刪除的節點只有左孩子* */if (cur == root) {root = cur.l;}if (hasLeft) {parent.l = cur.l;} else {parent.r = cur.l;}} else if (cur.l == null) {/*** 要刪除的節點只有右孩子* */if (cur == root) {root = cur.r;}if (hasLeft) {parent.l = cur.r;}else {parent.r = cur.r;}} else {/*** 要刪除的節點既有左孩子又有右孩子* 思路:用待刪除節點右子樹中的v值最小的結點來替代要刪除的節點,然后刪除右子樹中結點* 右子樹中v值最小的節點一定沒有左子樹,所以刪除的這個結點一定是屬于葉子節點或只有右子樹的節點* */Node directPostNode = getPost(cur);cur.v = directPostNode.v;}return true;}private static Node getPost(Node delNode) {Node parent = delNode;Node dir = delNode;Node cur = delNode.r;while (cur != null) {parent = dir;dir = cur;cur = cur.l;}if (dir != delNode.r) {//從樹中刪除此直接后繼節點parent.l = dir.r;dir.r = null;}return dir;}public static void preorder(Node node) {System.out.print(node.v + " ");if (node.l != null)preorder(node.l);if (node.r != null)preorder(node.r);}public static void main(String[] args) {/*** 插入* */insert(new Node(20));insert(new Node(10));insert(new Node(30));/*** 查找* */System.out.println(find(20));/*** 刪除* */delete(20);/*** 前序遍歷* */preorder(root);} }總結
以上是生活随笔為你收集整理的减治法在查找算法中的应用(JAVA)--二叉查找树的查找、插入、删除的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: sc.exe 详解
- 下一篇: Ruby Variable Scope