中文JAVA技術平等自由協作創造

          Java專題文章博客和開源

          常用鏈接

          統計

          最新評論

          數據結構之二叉樹的Java實現

            樹由邊連接的節點構成。節點一般代表實體數據,如代表某一類數據。windows文件系統就可以看成是一棵樹,比如C盤下有一些文件夾,這些文件夾下面又分別有一些文件夾,這樣的關系其實就是一棵樹。

            根:樹頂端的節點稱為樹的根,一棵樹只有一個根。

            父節點:每一個節點(除了根)都有一條邊向上連接到另一個節點,上面的這個節點就稱為下面節點的父節點。

            子節點:與父節點相反雅思答案 www.tygj123.com

            子樹:每個節點都可以作為子樹的根,它和它所有的子節點,還有子節點的子節點都在子樹中。

            二叉樹:如果樹中每個節點最多有兩個子節點,這樣的樹就稱為二叉樹。

            二叉樹的兩個節點分別稱為左子節點和右子節點。

            Java中表示二叉樹,可以用數組表示樹,常用的方法是將節點存在無關聯的容器中,再通過每個節點指向自己的子節點的引用來連接。

            下面的方法用的就是后一種:

            package test;

            public class BinaryTree {

            static Node root;

            public Node find(int key) {

            Node current = root;// 從根節點開始,用current保存正在查看的節點

            while (current.idata != key) {

            if (key < current.idata)

            current = current.leftChild;

            else

            current = current.rightChild;

            if (current == null)

            return null;

            }

            return current;

            }

            public void insert(int key) {

            // 首先要找到插入的地方

            Node inode = new Node();

            inode.idata = key;// 賦值

            if (root == null)

            root = inode;// 空樹,則作為根節點

            else {

            Node current = root;// 從根節點開始比對

            Node parent;

            while (true) {

            // 用parent來存儲current,目的是在current變為空的時候,

            // 才知道current== null時對應的上一個節點(parent)沒有子節點

            parent = current;

            if (key < current.idata) {

            current = current.leftChild;

            if (current == null) {

            parent.leftChild = inode;

            return;

            }

            } else {

            current = current.rightChild;

            if (current == null) {

            parent.rightChild = inode;

            return;

            }

            }

            }

            }

            }

            /**

            * 找到要刪除的節點 有三種情況:1)該節點是頁節點 ,2)該節點有一個子節點 ,3)該節點有兩個子節點

            * (刪除好復雜,于是可以這樣:在每一個節點上添加一個字段isDelete,若需要刪除,則置為true)

            */

            public boolean delete(int key) {

            Node current = root;

            Node parent = root;

            boolean isLeftChild = true;

            while (current.idata != key) {

            parent = current;

            if (key < current.idata) {

            isLeftChild = true;

            current = current.leftChild;

            } else {

            isLeftChild = false;

            current = current.rightChild;

            }

            if (current == null)

            return false;

            }// 找到了節點

            // 判斷有無子節點 www.wx-jr.com

            if (current.leftChild == null && current.rightChild == null) {

            if (current == root)

            root = null;

            else if (isLeftChild)

            parent.leftChild = null;

            else

            parent.rightChild = null;

            } else if (current.rightChild == null) {

            if (current == root)

            root = current.leftChild;

            else if (isLeftChild)

            parent.leftChild = current.leftChild;

            else

            parent.rightChild = current.leftChild;

            } else if (current.leftChild == null) {

            if (current == root)

            root = current.rightChild;

            else if (isLeftChild)

            parent.leftChild = current.rightChild;

            else

            parent.rightChild = current.rightChild;

            }

            /**

            * 刪除一個有兩個子節點的節點,就不能用它的一個子節點來代替它,而要用它的中序后繼代替該節點 如何找?

            * 首先,找到初始節點的右子節點rcn,然后轉到rcn的左子節點(有的話)rcnl,然后轉到rcnl的左子節點,直到結束。

            * 這里實際上要找的是比初始節點值大的集合中最小的那一個 如果初始節點的右子節點沒有左子節點,那么其本身就是后繼

            */

            else {

            Node success = getMidPostNode(current);

            if (current == root)

            root = success;

            else if (isLeftChild)

            parent.leftChild = success;

            else

            parent.rightChild = success;

            success.leftChild = current.leftChild;

            }

            return true;

            }

            // 獲取當前節點的中序后繼 www.sd-gw.com

            public Node getMidPostNode(Node delNode) {

            Node successParent = delNode;

            Node success = delNode;

            Node current = delNode.rightChild;

            while (current != null) {// 直到找到當前節點右子節點的最左子孫節點

            successParent = success;

            success = current;

            current = current.leftChild;

            }

            if (success != delNode.rightChild) {

            successParent.leftChild = success.rightChild;

            success.rightChild = delNode.rightChild;

            }

            return success;

            }

            // 前序遍歷

            public void preTraverse(Node root) {

            if (root != null) {

            System.out.println(root.idata + " ");

            preTraverse(root.leftChild);

            preTraverse(root.rightChild);

            }

            }

            // 中序遍歷

            public void midTraverse(Node root) {

            if (root != null) {

            midTraverse(root.leftChild);

            System.out.println(root.idata + " ");

            midTraverse(root.rightChild);

            }

            }

            // 后續遍歷

            public void postTraverse(Node root) {

            if (root != null) {

            postTraverse(root.leftChild);

            postTraverse(root.rightChild);

            System.out.println(root.idata + " ");

            }

            }

            // 遞歸地交換二叉樹的左右子節點

            public void swap(Node root) {

            if(root == null)

            return;

            Node tmp = root.leftChild;

            root.leftChild = root.rightChild;

            root.rightChild = tmp;

            swap(root.leftChild);

            swap(root.rightChild);

            }

            public static void main(String[] args) {

            BinaryTree bt = new BinaryTree();

            bt.insert(1);

            bt.insert(2);

            bt.insert(3);

            bt.insert(0);

            bt.insert(5);

            // Node f = bt.find(2);

            // System.out.println("find = " + f.idata);

            // bt.delete(3);

            // bt.preTraverse(root);

            // System.out.println("----------");

            // bt.midTraverse(root);

            // System.out.println("----------");

            // bt.postTraverse(root);

            // System.out.println("---------->");

            bt.printBinaryTree(root, 0);

            bt.swap(root);

            bt.printBinaryTree(root, 0);

            }

            //遞歸打印樹形二叉樹

            public static void printBinaryTree(Node root, int level){

            if(root==null)

            return;

            printBinaryTree(root.rightChild, level+1);

            if(level!=0){

            for(int i=0;i<LEVEL-1;I++) pre }< rightChild; Node leftChild; idata; int { } level+1); printBinaryTree(root.leftChild, System.out.println(root.idata); else System.out.println(?|-------?+root.idata); System.out.print(?|\t?);><BR>

            <BR>

            <P></P>

          posted on 2014-03-08 09:56 好不容易 閱讀(301) 評論(0)  編輯  收藏


          只有注冊用戶登錄后才能發表評論。


          網站導航:
           
          PK10開獎 PK10開獎
          主站蜘蛛池模板: 深州市| 晋宁县| 海林市| 图木舒克市| 洱源县| 乌拉特中旗| 堆龙德庆县| 海阳市| 包头市| 西充县| 南川市| SHOW| 垣曲县| 旅游| 麦盖提县| 泊头市| 健康| 芮城县| 板桥市| 昌吉市| 简阳市| 桓台县| 达尔| 张家川| 泸定县| 岱山县| 墨脱县| 泗水县| 涿州市| 西昌市| 历史| 长兴县| 宁津县| 江达县| 新沂市| 韶关市| 和田市| 东港市| 安义县| 福清市| 安阳县|