数据结构----->二叉树

来源:互联网 发布:mysql 断电 无法启动 编辑:程序博客网 时间:2024/05/23 18:31
            (1)数据结构----二叉树

具有数组和链表各自的特点:
1>像数组一样快速的查找
2>像链表一样快速添加
3>删除操作复杂

二叉树:每个节点最多有两个字数的有序树,在使用二叉树的时候,数据并不是随便插到节点中的,一个节点的左字节点的关键值必须小于此节点,右子节点的关键值必须大于或者等于此节点,所以称二叉查找树,二叉排序树,二叉搜索树.
完全二叉树:若设二叉树的高度为h,除第h层外,其他各层的节点数都达到最大个数,第h层有叶子节点,并且叶子节点都是从左到右一次排布
满二叉树:除了叶节点以外,每个节点都有左右孩子
深度:二叉树的层数
二叉树的(特点):
(1):树执行查找,删除,插入的时间复杂度都是O(logN)
(2):遍历二叉树的方法包括前,中,后
(3):非平衡树指的是根的左右两边的子节点的数量不一致
(4):在非空二叉树中,第i层的节点总数不超过2^(n-1)
(5):深度为h的二叉树最多有2^(h)-1
(6):对于任意一颗二叉树,如果其叶节点数为N0,而度为二的节点数为N2则N0=N2+1;

        /** 树的节点定义*/class Node {    private Node lchild;// 左孩子    private Node rchild;// 右孩子    private int value;    private boolean isDelete;    public Node getlchildNode() {        return lchild;    }    public void setlchildNode(Node lchild) {        this.lchild = lchild;    }    public Node getrchildNode() {        return rchild;    }    public void setrchildNode(Node rchild) {        this.rchild = rchild;    }    public int getValue() {        return value;    }    public void setValue() {        this.value = value;    }    public boolean getdelete() {        return isDelete;    }    public void setdelete(boolean isDelete) {        this.isDelete = isDelete;    }    public Node() {    }    public Node(Node lchild, Node rchild, int value, boolean isDelete) {        super();        this.lchild = lchild;        this.rchild = rchild;        this.value = value;        this.isDelete = isDelete;    }    public Node(int value) {        this(null, null, value, false);    }    public String toString() {        return "Node[lchild=" + lchild + ",rchild=" + rchild + ",value="                + value + ",isDelete=" + isDelete + "]";    }}/** 二叉树的实现代码 ,插入操作*/class BTree {    // 根节点    private Node root;    public Node getRoot() {        return root;    }    /** 插入操作 */    public void insert(int value) {        Node node = new Node(value);        if (root == null) {            root = node;            root.setlchildNode(null);            root.setrchildNode(null);        } else {            Node currentNode = root;            Node parentNode;            while (true) {                parentNode = currentNode;                if (node.getValue() > currentNode.getValue()) {                    currentNode = currentNode.getrchildNode();                    if (currentNode == null) {                        parentNode.setrchildNode(node);                        return;                    }                } else {                    // 左边                    currentNode = currentNode.getlchildNode();                    if (currentNode == null) {                        parentNode.setlchildNode(node);                        return;                    }                }            }        }    }}

/* 二叉树的查找 /
public Node find(int key) {
Node currentNode = root;
if (currentNode != null) {
while (currentNode.getValue() != key) {
if (currentNode.getValue() > key) {
currentNode = currentNode.getlchildNode();

                } else {                    currentNode = currentNode.getrchildNode();                }                if (currentNode == null) {                    return null;                }            }            if (currentNode.getdelete()) {                return null;            } else {                return currentNode;            }        } else {            return null;        }    }}

/* 构建完全二叉树 /
public CreateTree() {
pnum = aa.length / 2;
root = null;
nodelist = new LinkedList();
for (int index = 0; index < aa.length; index++) {
nodelist.add(new Node(aa[index]));

    }    for (int i = 0; i < pnum; i++) {        pnode = nodelist.get(i);// 拿到父亲节点        // 设置左孩子        pnode.setlchild(nodelist.get(2 * i + 1));        if ((2 * i + 2) < nodelist.size()) {            // 右孩子            pnode.setrchild(nodelist.get(2 * i + 2));        }        // 因为最后一个父节点可能没有右孩子,所以单独拿出来处理        int lastpnode = aa.length / 2 - 1;        nodelist.get(lastpnode).lchild = nodelist.get(lastpnode * 2 + 1);        if (aa.length % 2 == 1) {            nodelist.get(lastpnode).rchild = nodelist                    .get(lastpnode * 2 + 2);        }    }}/** 前序遍历 */public static void pro(Node node) {    if (node == null) {        return;    }    System.out.print(node.data + "");    pro(node.lchild);    pro(node.rchild);}/** 中序遍历 */public static void Ino(Node node) {    if (node == null) {        return;    }    Ino(node.lchild);    System.out.print(node.data + "");    Ino(node.rchild);}/** 后序遍历 */public static void por(Node node) {    if (node == null) {        return;    }    por(node.lchild);    por(node.rchild);    System.out.print(node.data + "");}/** 非递归----》前序遍历 */    public void preOrder(notTree  t) {        // 采用顺序        Stack<notTree> s = new Stack<notTree>();        while (t != null || !s.empty()) {            while (t != null) {                System.out.print(t.data);                s.push(t);//入栈                t=t.lchild;            }            if(!s.empty()){        t=s.pop();//出栈        t=t.rchild;            }        }    }

/*非递归中序遍历/
public void InOrder(notTree t){
Stack ss=new Stack();
while(t!=null||!ss.empty()){
while(t!=null){
ss.push(t);
t=t.lchild;
}
if(!ss.empty()){
ss.pop();
System.out.print(t.data);
t=t.rchild;

            }        }    }    /**非递归后序 */

这里需要说明一下,后序遍历相对于前面的来说相对比较复杂。
二叉树的后序遍历顺序为,root–>lchild,rooot—>rchild, root.
所以我们要保存根节点的状态,用栈来模拟递归的过程
方法:对于节点s有以下情况
1>s如果是叶子节点,直接输出
2>s如果有孩子,且孩子没有被访问过,则按照右孩子,左孩子的顺序依次入栈
3>s如果有孩子,且孩子都已经访问过,则访问s节点
(1)(怎样来表示s是否被访问过,一般都会想到对每个节点的状态进行保存,但是空间复杂度太大)
(2)可以保存最后一个访问的节点last如果满足(p-rchild>NULL&&p->lchild||last=p->rchild)那么显然我们p的孩子都访问过了,接下来访问p)
/*二叉树非递归后序遍历 /

    public void PostOrder(notTree t) {        Stack<notTree> sss = new Stack<notTree>();        Stack<Integer> s2 = new Stack<Integer>();        Integer i = new Integer(1);        while (t != null || !sss.empty()) {            while (t != null) {                sss.push(t);                s2.push(new Integer(0));                t = t.lchild;            }            while (!sss.empty() && s2.peek().equals(i)) {                s2.pop();                System.out.print(sss.pop().data);            }            if (!sss.empty()) {                s2.pop();                s2.push(new Integer(1));                t = sss.peek();                t = t.rchild;            }        }    }
0 0
原创粉丝点击