博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
Java数据结构和算法-树
阅读量:2443 次
发布时间:2019-05-10

本文共 8859 字,大约阅读时间需要 29 分钟。

树的概念:

树是数据元素之间具有次层关系的非线性的结构,树是由n(n≥0)个结点组成的有限集合,n=0的树是空树。    

二叉树:

二叉树(Binary Tree)是n(n≥0)个结点组成的有限集合,n=0时称为空二叉树;n>0的二叉树由一个根结点和两棵互不相交、分别称为左子树和右子树的子二叉树构成,二叉树也是递归定义的,在树种定义的度、层次等术语,同样适用于二叉树。

完全二叉树:

对于一个具有n个结点的二叉树按层序编号,如果编号为i(1-n)的结点与同样深度的满二叉树编号为i的结点在二叉树中位置完全相同,则这颗二叉树称为完全二叉树。

二叉树的性质:

性质1:在二叉树的第i层上至多有2i-1个结点(i>=1)。

性质2:深度为k的二叉树至多有2k-1个结点(k>=1)。

性质3:对任何一颗二叉树T,如果其终端结点数为n0,度为2的结点数为n2,则n0 = n2+1.

性质4:具有n个结点的完全二叉树深度为[log2n]+1。 ([x]表示不大于x的最大整数)。

性质5:如果对一颗有n个结点的完全二叉树(其深度为[log2n]+1)  的结点按层序编号(从第1层到第[log2n]+1层,每层从左到  右),对任意一个结点i(1<=i<=n)有:

1)如果i=1,则结点i是二叉树的根,无双亲;如果i>1,则其双亲是结点[i/2]

2)如果2i>n,则结点i无左孩子(结点i为叶子结点);否则其左孩  子是结点2i。

3)如果2i+1>n,则结点i无右孩子;否则其右孩子是结点2i+1。

二叉树的遍历:

前序遍历:根->左->右(左图:ABDGHCEIF)

中序遍历:左->根->右(中图:GDHBAEICF)

后序遍历:左->右->根(右图:GHDBIEFCA)

性质1:在二叉树的第i层上至多有2i-1个结点(i>=1)。

package com.structures.tree;import java.util.ArrayList;import java.util.Stack;public class BinaryTree {    private TreeNode root=null;    public BinaryTree(){        root=new TreeNode(1,"A");    }    public void createBinaryTree(){		TreeNode nodeB=new TreeNode(2,"B");		TreeNode nodeC=new TreeNode(3,"C");		TreeNode nodeD=new TreeNode(4,"D");		TreeNode nodeE=new TreeNode(5,"E");		TreeNode nodeF=new TreeNode(6,"F");		root.leftChild=nodeB;		root.rightChild=nodeC;		nodeB.leftChild=nodeD;		nodeB.rightChild=nodeE;		nodeC.rightChild=nodeF;    }    /**     * 求二叉树的高度     */    public int getHeight(){        return getHeight(root);    }    private int getHeight(TreeNode node) {        if(node==null){            return 0;        }else{            int i=getHeight(node.leftChild);            int j=getHeight(node.rightChild);            return (i
stack=new Stack
(); if(node==null){ return; }else{ stack.push(node); while(!stack.isEmpty()){ TreeNode n=stack.pop(); System.out.println("nonPreOrder data"+n.getData()); if(n.rightChild!=null){stack.push(n.rightChild);} if(n.leftChild!=null){stack.push(n.leftChild);} } } } /** * 中序遍历--非迭代法 */ public void nonMidOrder(TreeNode node) { Stack
stack = new Stack
(); TreeNode p = node; while (p != null || !stack.isEmpty()) { while (p != null) { stack.push(p); p = p.getLeftChild(); } if (!stack.isEmpty()) { TreeNode n = stack.pop(); System.out.println("nonMidOrder data"+n.getData()); p = n.getRightChild(); } } } public void nonLastOrder(TreeNode node) { Stack
stack = new Stack
(); TreeNode cur, pre = null; stack.push(node); while (!stack.empty()) { cur = stack.peek(); if ((cur.getLeftChild() == null && cur.getRightChild() == null)||(pre != null && (cur.getLeftChild() == pre||cur.getRightChild() == pre))) { TreeNode temp = stack.pop(); System.out.print(" "+temp.getData()); pre = temp; } else { if (cur.getRightChild() != null) stack.push(cur.getRightChild()); if (cur.getLeftChild() != null) stack.push(cur.getLeftChild()); } } } /** * 创建二叉树 */ public void createBinaryTreePre(ArrayList
data){ createBinaryTree(data.size(),data); } private TreeNode createBinaryTree(int size,ArrayList
data){ if(data.size()==0){ return null; } String d=data.get(0); int index=size-data.size(); TreeNode node; if("#".equals(d)){ node=null; data.remove(0); return node; } node=new TreeNode(index,d); if(index==0){ root=node; } data.remove(0); node.leftChild=createBinaryTree(size,data); node.rightChild=createBinaryTree(size,data); return node; } public class TreeNode{ private int index; private String data; private TreeNode leftChild; private TreeNode rightChild; public TreeNode(int index,String data){ this.index=index; this.data=data; this.leftChild=null; this.rightChild=null; } public int getIndex() { return index; } public void setIndex(int index) { this.index = index; } public String getData() { return data; } public void setData(String data) { this.data = data; } public TreeNode getLeftChild() { return leftChild; } public void setLeftChild(TreeNode leftChild) { this.leftChild = leftChild; } public TreeNode getRightChild() { return rightChild; } public void setRightChild(TreeNode rightChild) { this.rightChild = rightChild; } } public static void main(String[] args) { BinaryTree binaryTree=new BinaryTree(); binaryTree.createBinaryTree(); int height=binaryTree.getHeight(); System.out.println("height:"+height); int size=binaryTree.getSize(); System.out.println("size:"+size);// binaryTree.preOrder(binaryTree.root);// binaryTree.midOrder(binaryTree.root);// binaryTree.lastOrder(binaryTree.root);// binaryTree.nonPreOrder(binaryTree.root);// binaryTree.nonMidOrder(binaryTree.root);// String[] strs=new String[]{"A","B","D","#","#","E","#","#","C","#","F","#","#"};// ArrayList
list=new ArrayList<>();// for(String str:strs){// list.add(str);// }// binaryTree.createBinaryTreePre(list);// binaryTree.midOrder(binaryTree.root);// binaryTree.nonPreOrder(binaryTree.root);//// binaryTree.nonMidOrder(binaryTree.root); binaryTree.lastOrder(binaryTree.root); binaryTree.nonLastOrder(binaryTree.root); }}

性质2:深度为k的二叉树至多有2k-1个结点(k>=1)。

赫夫曼树基本概念:

  别名“最优树”,是一种带权路径最短的树。

(1)路径:从树中一个结点到另一个结点之间的分支构成这两个结点之间的路径。

(2)路径长度:路径上的分支数目。

(3)树的路径长度:从树根到一每结点的路径长度之和。

(4)结点的带权路径长度:从该结点到树根之间的路径长度与结点上权值的乘积。

(5)树的带权路径长度:树中所有叶子结点的带权路径长度之和。记作:WPL

 

如图:

二叉树a的树路径长度:1+1+2+2+3+3+4+4=20

二叉树b的树路径长度:1+1+2+2+2+2+3+3=16

二叉树a的WPL:5*1+15*2+40*3+30*4+10*4=315

二叉树b的WPL:10*2+30*2+40*2+15*3+5*3=220

性质3:对任何一颗二叉树T,如果其终端结点数为n0,度为2  结点  n2,则n0 = n2+1.

性质4:二具有n个结点的完全二叉树深度为[log2n]+1 ([x]表示  大于  x的最大整数)

赫夫曼树的构造:

2).如果2i>n,则结点i无左孩子(结点i为叶子结点);否则其左  是结点2

3).如果2i+1>n,则结点i无右孩子;否则其右孩子是结点2i+1。he fu man

赫夫曼树的应用:

 二叉查找树:

   二叉查找树,也叫二叉搜索树、有序二叉树,排序二叉树,满足以下性质(非严谨描述):

      1.对于每个节点,其左子节点要么为空,要么值小于该节点值。

      2.对于每个节点,其右子节点要么为空,要么值大于该节点值。

      3.没有键值相等的点。

      通俗的归纳一下性质,二叉查找树中每个节点的值都大于其左子节点,小于其右子节点(如果左右子节点存在的话)。所以二叉查找树中每个节点的左边,整棵左树都是小于它的节点;右边,整棵右树都是大于它的节点。

package com.structures.tree;public class SearchBinaryTree {    public static void main(String[] args) {        SearchBinaryTree binaryTree=new SearchBinaryTree();        binaryTree.createBinaryTree();        int[] intArray={3,54,56,4,67,50,89,5,7,12};        for(int i:intArray){            binaryTree.put(i);        }        System.out.print("中序遍历必然是递增序列:");        midOrder(binaryTree.root);    }    private TreeNode root;    public SearchBinaryTree(){    }    public void createBinaryTree(){        root=new TreeNode(1,40);       TreeNode nodeB=new TreeNode(2,30);       TreeNode nodeC=new TreeNode(3,60);       TreeNode nodeD=new TreeNode(4,25);       TreeNode nodeE=new TreeNode(5,35);       TreeNode nodeF=new TreeNode(6,70);        root.leftChild=nodeB;        root.rightChild=nodeC;        nodeB.leftChild=nodeD;        nodeB.rightChild=nodeE;        nodeC.rightChild=nodeF;    }    public static void midOrder(TreeNode node){        if(node==null){            return;        }else{            midOrder(node.leftChild);            System.out.print(node.data+" ");            midOrder(node.rightChild);        }    }    class TreeNode{        private int key;        private TreeNode leftChild;        private TreeNode rightChild;        private TreeNode parent;        private int data;        public TreeNode(int key,int data){            this.key=key;            this.data=data;            this.leftChild=null;            this.rightChild=null;            this.parent=null;        }        public int getKey() {            return key;        }        public void setKey(int key) {            this.key = key;        }        public TreeNode getLeftChild() {            return leftChild;        }        public void setLeftChild(TreeNode leftChild) {            this.leftChild = leftChild;        }        public TreeNode getRightChild() {            return rightChild;        }        public void setRightChild(TreeNode rightChild) {            this.rightChild = rightChild;        }        public TreeNode getParent() {            return parent;        }        public void setParent(TreeNode parent) {            this.parent = parent;        }        public int getData() {            return data;        }        public void setData(int data) {            this.data = data;        }    }    /**     * 向查找二叉树添加结点     */    public TreeNode put(int data) {        TreeNode node = null;        TreeNode parent = null;        if (root == null) {            node = new TreeNode(0, data);            root = node;        }        node=root;        while (node != null) {            parent = node;            if (data < node.data) {                node = node.leftChild;            } else if (data > node.data) {                node = node.rightChild;            } else {                return node;            }        }        node=new TreeNode(0,data);        if(data

 

 

你可能感兴趣的文章
掌握React.Memo
查看>>
golang 延迟_了解Go中的延迟
查看>>
react 组件样式_如何设置React组件的样式
查看>>
node.js 模块_如何创建Node.js模块
查看>>
centos上安装git_如何在CentOS 8上安装Git
查看>>
在JavaScript中优化switch语句
查看>>
express 模板引擎_了解Express模板引擎
查看>>
如何在CentOS 8上安装Node.js
查看>>
如何在Ubuntu 20.04上安装Git
查看>>
javascript深度图_在JavaScript中深度克隆对象(及其工作方式)
查看>>
centos ssh密钥_如何在CentOS 8上设置SSH密钥
查看>>
debian 10 安装_如何在Debian 10上安装Webmin
查看>>
使用CentOS 8进行初始服务器设置
查看>>
ecmascript v3_节点v12中的新ECMAScript模块简介
查看>>
盖茨比乔布斯_通过盖茨比使用Airtable
查看>>
mern技术栈好处?_如何开始使用MERN堆栈
查看>>
路由器接路由器_路由器之战:到达路由器vsReact路由器
查看>>
rxjs 搜索_如何使用RxJS构建搜索栏
查看>>
如何在Debian 10上安装MariaDB
查看>>
react-notifications-component,一个强大的React Notifications库
查看>>