演算法導論學習筆記——二叉尋找樹

來源:互聯網
上載者:User
//SearchTree類public class SearchTree {/** * 中序遍曆:根據二叉尋找樹的性質,中序遍曆將按排列順序輸出樹中的所有關鍵字。 * @param root */public static void inorderTree(Node root){if(root!=null){inorderTree(root.getLchild());System.out.println(root.getKey());inorderTree(root.getRchild());}}/** * 關鍵字查詢:該過程從樹的根結點開始進行尋找,並沿著樹下降。 * 對碰到的每個結點,比較其關鍵字。如果兩個關鍵字相同,則尋找結束; * 如果結點關鍵字大於查詢關鍵字,則繼續尋找結點的左子樹;如果結點關鍵字小於或等於查詢關鍵字,則繼續尋找結點的右子樹。 * @param root * @param value * @return */public static Node treeSearch(Node root,int value){Node temp = root;while(temp!=null&&temp.getKey()!=value){if(value<temp.getKey())temp = temp.getLchild();elsetemp = temp.getRchild();}if(value==temp.getKey())return temp;elsereturn null;}/** * 最大關鍵字結點:要尋找二叉樹中具有最大關鍵字的結點, * 只要從根結點開始,沿著各結點的right指標查詢下去,直到遇到NULL為止。 * @param root * @return */public static Node treeMax(Node root){Node temp = root;while(null!=temp.getRchild()){temp = temp.getRchild();}return temp;}/** *最小關鍵字結點: 要尋找二叉樹中具有最小關鍵字的結點,只要從根結點開始,沿著各結點的left指標查詢下去,直到遇到NULL為止。 * @param root * @return */public static Node treeMin(Node root){Node temp = root;while(null!=temp.getLchild()){temp = temp.getLchild();}return temp;}/** * 前趨結點:給定一個二叉尋找樹中的結點,它的前趨結點是在中序遍曆順序下它的前一個結點。 * 如果給定查詢結點的左子樹不為空白,則它的前趨結點是左子樹中的最大關鍵字結點; * 如果左子樹為空白,需要向上判斷每一個父結點,直到父結點為空白或者遍曆結點是父結點的右子結點時,根據中序遍曆性質,該父結點即為查詢結點的前趨。 * @param root * @return */public static Node treePredecessor(Node node){Node preNode = null;Node tempNode = null;if(node.getLchild()!=null)return treeMax(node.getLchild());System.out.println("----");preNode = node.getParent();tempNode = node;while(preNode!=null&&preNode.getRchild()!=tempNode){tempNode = preNode;preNode = preNode.getParent();}return preNode;}/** * 後繼結點:與前趨結點相反,它是在中序遍曆順序下的後一個結點。 * 如果給定查詢結點的右子樹不為空白,則它的後繼結點是右子樹中的最小關鍵字結點; * 如果右子樹為空白,需要向上判斷每一個父結點,直到父結點為空白或者遍曆結點是父結點的左子結點時,則該父結點即為查詢結點的後繼。 * @param node * @return */public static Node treeSuccessor(Node node){Node preNode = null;Node tempNode = null;if(node.getRchild()!=null)return treeMin(node.getRchild());preNode = node.getParent();tempNode = node;while(preNode!=null&&preNode.getLchild()!=tempNode){tempNode = preNode;preNode = preNode.getParent();}return preNode;}/** * 插入操作:插入操作從根結點開始,沿樹下降,並不斷比較當前結點與要插入結點的關鍵字, * 以決定向左轉或向右轉,直到當前結點為空白,這個空所在的位置即是將要插入的位置。 * 最後,修改插入結點的父結點指標,並根據與父結點關鍵字的比較結果,修改父結點的子結點指標。 * 如果父結點為空白,說明二叉尋找樹是空的,這時,將新插入結點作為樹的根結點。 * 由於每次都將新結點插入到葉子結點的位置,通過這種插入操作構建的二叉尋找樹往往很不平衡,高度值較大,使得查詢操作的已耗用時間較大。 * @param root * @param node */public static void treeInsert(Node root,Node node){Node tempNode = root;Node parentNode = null;while(tempNode!=null){parentNode = tempNode;if(node.getKey()<tempNode.getKey())tempNode = tempNode.getLchild();elsetempNode = tempNode.getRchild();}if(null==parentNode)root = node;else if(node.getKey()<parentNode.getKey()){parentNode.setLchild(node);}else{parentNode.setRchild(node);}node.setParent(parentNode);}/** * 刪除操作有三種情況:         * 1)如果要刪除的結點沒有子結點,則只要修改其父結點的對應子結點指標為空白; * 2)如果要刪除的結點只有一個子結點,則可以通過其子結點與其父結點間建立一條連結來刪除該結點; * 3)如果要刪除的結點有兩個子結點,可以先刪除該結點的後繼結點(這裡的後繼結點一定在右子樹中,並且該後繼結點不可能有左子結點), *      再用後繼結點的內容來替換要刪除結點的內容(實際上,這裡使用前趨結點來替換也是可行的)。 * 下面的操作分為四個步驟: *  1)確定要刪除的結點(當沒有子結點或只有一個子結點時就是該結點本身;當有兩個子結點時就是該結點的後繼結點); *  2)確定要刪除結點的子結點,這裡,要麼沒有子結點,要麼只有一個; *  3)在要刪除結點的父子結點之間建立連結,如果父結點為空白,說明要刪除的是樹的根結點; *  4)如果刪除的是後繼結點,則進行內容替換。 * @param root * @param node */public static void treeDelete(Node root,Node node){Node tempNode = null;Node childNode = null;//步驟1if(node.getLchild()==null||node.getRchild()==null)tempNode = node;elsetempNode = treeSuccessor(node);//步驟2if(tempNode.getLchild()!=null)childNode = tempNode.getLchild();elsechildNode = tempNode.getRchild();//步驟3if(childNode!=null)childNode.setParent(tempNode.getParent());if(tempNode.getParent()==null)root = childNode;else if(tempNode==tempNode.getParent().getLchild())tempNode.getParent().setLchild(childNode);elsetempNode.getParent().setRchild(childNode);//步驟4if(tempNode!=node)node.setKey(tempNode.getKey());}//test.....public static void main(String args[]){int arr[]={15,5,3,12,10,13,6,7,16,20,18,23};Node root = new Node(15);for(int i = 1;i<arr.length;i++)treeInsert(root,new Node(arr[i]));/*inorderTree(root);*//*Node temp = treeSearch(root,18); * if(null!=temp)System.out.println(temp.getKey());*//*Node temp = treeMax(root); *      if(null!=temp)System.out.println(temp.getKey());*//*Node temp = treeMin(root); * if(null!=temp)System.out.println(temp.getKey());*/Node node = treeSearch(root,5);Node temp = treePredecessor(node);if(null!=temp)System.out.println(temp.getKey());/*Node temp = treeSuccessor(node);if(null!=temp)System.out.println(temp.getKey());*//*treeDelete(root,new Node(5));inorderTree(root);*/}}

Node類:

public class Node {private int key;private Node lchild;private Node rchild;private Node parent;public Node(int key){this.key = key;this.lchild = null;this.rchild = null;this.parent = null;}public Node(int key,Node lchild,Node rchild,Node parent){this.key = key;this.lchild = lchild;this.rchild = rchild;this.parent = parent;}public int getKey() {return key;}public void setKey(int key) {this.key = key;}public Node getLchild() {return lchild;}public void setLchild(Node lchild) {this.lchild = lchild;}public Node getRchild() {return rchild;}public void setRchild(Node rchild) {this.rchild = rchild;}public Node getParent() {return parent;}public void setParent(Node parent) {this.parent = parent;}

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.