中文JAVA技術(shù)平等自由協(xié)作創(chuàng)造

          Java專題文章博客和開源

          常用鏈接

          統(tǒng)計(jì)

          最新評(píng)論

          數(shù)據(jù)結(jié)構(gòu)之二叉樹的Java實(shí)現(xiàn)

            樹由邊連接的節(jié)點(diǎn)構(gòu)成。節(jié)點(diǎn)一般代表實(shí)體數(shù)據(jù),如代表某一類數(shù)據(jù)。windows文件系統(tǒng)就可以看成是一棵樹,比如C盤下有一些文件夾,這些文件夾下面又分別有一些文件夾,這樣的關(guān)系其實(shí)就是一棵樹。

            根:樹頂端的節(jié)點(diǎn)稱為樹的根,一棵樹只有一個(gè)根。

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

            子節(jié)點(diǎn):與父節(jié)點(diǎn)相反雅思答案 www.tygj123.com

            子樹:每個(gè)節(jié)點(diǎn)都可以作為子樹的根,它和它所有的子節(jié)點(diǎn),還有子節(jié)點(diǎn)的子節(jié)點(diǎn)都在子樹中。

            二叉樹:如果樹中每個(gè)節(jié)點(diǎn)最多有兩個(gè)子節(jié)點(diǎn),這樣的樹就稱為二叉樹。

            二叉樹的兩個(gè)節(jié)點(diǎn)分別稱為左子節(jié)點(diǎn)和右子節(jié)點(diǎn)。

            Java中表示二叉樹,可以用數(shù)組表示樹,常用的方法是將節(jié)點(diǎn)存在無關(guān)聯(lián)的容器中,再通過每個(gè)節(jié)點(diǎn)指向自己的子節(jié)點(diǎn)的引用來連接。

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

            package test;

            public class BinaryTree {

            static Node root;

            public Node find(int key) {

            Node current = root;// 從根節(jié)點(diǎn)開始,用current保存正在查看的節(jié)點(diǎn)

            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;// 空樹,則作為根節(jié)點(diǎn)

            else {

            Node current = root;// 從根節(jié)點(diǎn)開始比對(duì)

            Node parent;

            while (true) {

            // 用parent來存儲(chǔ)current,目的是在current變?yōu)榭盏臅r(shí)候,

            // 才知道current== null時(shí)對(duì)應(yīng)的上一個(gè)節(jié)點(diǎn)(parent)沒有子節(jié)點(diǎn)

            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;

            }

            }

            }

            }

            }

            /**

            * 找到要?jiǎng)h除的節(jié)點(diǎn) 有三種情況:1)該節(jié)點(diǎn)是頁節(jié)點(diǎn) ,2)該節(jié)點(diǎn)有一個(gè)子節(jié)點(diǎn) ,3)該節(jié)點(diǎn)有兩個(gè)子節(jié)點(diǎn)

            * (刪除好復(fù)雜,于是可以這樣:在每一個(gè)節(jié)點(diǎn)上添加一個(gè)字段isDelete,若需要?jiǎng)h除,則置為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;

            }// 找到了節(jié)點(diǎn)

            // 判斷有無子節(jié)點(diǎn) 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;

            }

            /**

            * 刪除一個(gè)有兩個(gè)子節(jié)點(diǎn)的節(jié)點(diǎn),就不能用它的一個(gè)子節(jié)點(diǎn)來代替它,而要用它的中序后繼代替該節(jié)點(diǎn) 如何找?

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

            * 這里實(shí)際上要找的是比初始節(jié)點(diǎn)值大的集合中最小的那一個(gè) 如果初始節(jié)點(diǎn)的右子節(jié)點(diǎn)沒有左子節(jié)點(diǎn),那么其本身就是后繼

            */

            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;

            }

            // 獲取當(dāng)前節(jié)點(diǎn)的中序后繼 www.sd-gw.com

            public Node getMidPostNode(Node delNode) {

            Node successParent = delNode;

            Node success = delNode;

            Node current = delNode.rightChild;

            while (current != null) {// 直到找到當(dāng)前節(jié)點(diǎn)右子節(jié)點(diǎn)的最左子孫節(jié)點(diǎn)

            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);

            }

            }

            // 后續(xù)遍歷

            public void postTraverse(Node root) {

            if (root != null) {

            postTraverse(root.leftChild);

            postTraverse(root.rightChild);

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

            }

            }

            // 遞歸地交換二叉樹的左右子節(jié)點(diǎn)

            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 好不容易 閱讀(306) 評(píng)論(0)  編輯  收藏


          只有注冊(cè)用戶登錄后才能發(fā)表評(píng)論。


          網(wǎng)站導(dǎo)航:
           
          PK10開獎(jiǎng) PK10開獎(jiǎng)
          主站蜘蛛池模板: 通州市| 揭西县| 内江市| 开封县| 新竹市| 紫金县| 沿河| 马山县| 衡水市| 瑞金市| 腾冲县| 化隆| 屯留县| 周宁县| 绥宁县| 长沙县| 来凤县| 荔波县| 济南市| 固镇县| 彩票| 琼结县| 武宁县| 抚顺市| 杭锦后旗| 保定市| 达州市| 平山县| 浏阳市| 定边县| 蕉岭县| 牡丹江市| 阿坝县| 塔城市| 正镶白旗| 普兰店市| 石狮市| 岳阳市| 浪卡子县| 曲水县| 天全县|