二叉树基本实现

二叉树模型

二叉树


基本结点

public  class Node { 
		Object data;
		Node leftChild;
		Node rightChild;
		public Node(Object data, Node leftChild, Node rightChild) {
			super();
			this.data = data;
			this.leftChild = leftChild;
			this.rightChild = rightChild;
		}
	}

二叉树接口

//二叉树接口
public interface Tree {
	
	public int size();
	
	public boolean isEmpty();
	
	public int getHeight();
	
	public void preTraversal();
	
	public void middleTraversal();
	
	public void postTraversal();
	
	//借助队列实现层次遍历
	public void orderByQueue();
	
	//借助栈实现非递归遍历二叉树,使用先序进行遍历
	public void preTraByStack();
	//借助栈实现非递归遍历二叉树,使用中序进行遍历
	void inOrderByStack();
	//借助栈实现非递归遍历二叉树,使用后序进行遍历
	void postTraByStack();
}

接口实现

public class LinkedBinaryTree implements Tree {

    private Node root;
    private Node node;

    public LinkedBinaryTree() {
    }

    public LinkedBinaryTree(Node root) {
        this.root = root;
    }

    @Override
    public int size() {
        System.out.print("树的大小:");
        return this.size(root);
    }

    private int size(Node node) {
        if (null == node) {
            return 0;
        } else {
            //获取左子树的size
            int ln = this.size(node.leftChild);
            //获取右子树的size
            int rn = this.size(node.rightChild);
            //左子树+右子树的size+1
            return ln + rn + 1;
        }
    }

    @Override
    public boolean isEmpty() {
        return root == null ? true : false;
    }

    @Override
    public int getHeight() {
        System.out.print("Tree的高度:");
        return this.getHeight(root);
    }

    private int getHeight(Node node) {
        if (null == node) {
            return 0;
        } else {
            //获取左子树的高度
            int ln = this.getHeight(node.leftChild);
            //获取右子树的高度
            int rn = this.getHeight(node.rightChild);
            //取较大的值并加上根高度
            return ln > rn ? ln + 1 : rn + 1;
        }
    }

    @Override
    public void preTraversal() {
        System.out.print("前序遍历:");
        this.preTraversal(root);
    }

    private void preTraversal(Node node) {
        if (null != node) {
            //输出根节点值
            System.out.print(node.data + ",");
            //对左子树先序遍历
            this.preTraversal(node.leftChild);
            //对右子树先序遍历
            this.preTraversal(node.rightChild);
        }
    }

    @Override
    public void middleTraversal() {
        System.out.print("\n中序遍历:");
        this.middleTraversal(root);
    }

    private void middleTraversal(Node node) {
        if (null != node) {
            //对左子树先序遍历
            this.middleTraversal(node.leftChild);
            //输出根节点值
            System.out.print(node.data + ",");
            //对右子树先序遍历
            this.middleTraversal(node.rightChild);
        }
    }

    @Override
    public void postTraversal() {
        System.out.print("\n后序遍历:");
        this.postTraversal(root);
    }

    private void postTraversal(Node node) {
        if (null != node) {
            //对左子树先序遍历
            this.postTraversal(node.leftChild);
            //对右子树先序遍历
            this.postTraversal(node.rightChild);
            //输出根节点值
            System.out.print(node.data + ",");
        }
    }

    @Override
    public void orderByQueue() {
        System.out.print("\n通过队列实现遍历二叉树:");
        if (null == root) return;
        Queue<Node> queue = new LinkedList<Node>();
        queue.add(root);
        while (queue.size() != 0) {
            int len = queue.size();
            for (int i = 0; i < len; i++) {
                Node temp = queue.poll();
                System.out.print(temp.data + ",");
                if (null != temp.leftChild) queue.add(temp.leftChild);
                if (null != temp.rightChild) queue.add(temp.rightChild);
            }
        }
    }

    @Override
    public void preTraByStack() {
        System.out.print("\n通过栈实现先序遍历二叉树:");
        Deque<Node> stack = new LinkedList<Node>();
        Node current = root;
        while (null != current || !stack.isEmpty()) {
            while (null != current) {
                System.out.print(current.data + ",");
                stack.push(current);
                current = current.leftChild;
            }
            if (!stack.isEmpty()) {
                current = stack.pop();
                current = current.rightChild;
            }
        }
    }


    @Override
    public void inOrderByStack() {
        System.out.print("\n通过栈实现中序遍历二叉树:");
        Deque<Node> stack = new LinkedList<Node>();
        Node current = root;
        while (null != current || !stack.isEmpty()) {
            while (null != current) {
                stack.push(current);
                current = current.leftChild;
            }
            if (!stack.isEmpty()) {
                current = stack.pop();
                System.out.print(current.data + ",");
                current = current.rightChild;
            }
        }
    }


    @Override
    public void postTraByStack() {
        System.out.print("\n通过栈实现后序遍历二叉树:");
        //新建栈,先进后出,将根结点入栈,双端队列
        Deque<Node> stack = new LinkedList<>();
        //新建一个list,记录结点的状态是否已经被访问过
        ArrayList<Node> list = new ArrayList<>();
        Node node = root;
        int flag;
        //首先检查完树的左子树,再右子树,最后将根节点输出
        while (node != null || stack.size() > 0) {
            //将最左子树添加完毕
            while (node != null) {
                stack.push(node);
                node = node.leftChild;
            }
            //和中序遍历相似,为先输出左结点,但是做结点输出完毕之后,不能直接将根结点弹出,而是必				Binary Tree须先将右结点弹出,
            //最后再将根结点弹出来,就会牵扯到一个根结点的访问状态的问题,是否已经被遍历过了
            //利用一个list集合记录已将被遍历过的根结点,防止产生死循环
            if (stack.size() > 0) {
                Node peek = stack.peek();
                if (peek.rightChild != null) {
                    boolean con = list.contains(peek);
                    if (con == true) {
                        Node pop = stack.pop();
                        System.out.print(pop.data + ",");
                    } else {
                        list.add(peek);
                        node = peek.rightChild;
                    }
                } else {
                    Node pop = stack.pop();
                    System.out.print(pop.data + ",");
                }
            }
        }
    }

    @Override
    public Node findKey(int key) {
        return this.findKey(root, key);
    }

    private Node findKey(Node root, Object key) {
        if (null == root) {
            return null;
        } else if (null != root && key == root.data) {
            return root;
        } else {
            Node node1 = this.findKey(root.leftChild, key);
            Node node2 = this.findKey(root.rightChild, key);
            if (null != node1 && key == node1.data) {
                return node1;
            }
            if (null != node2 && key == node2.data) {
                return node2;
            }
            return null;
        }
    }

main方法

public static void main(String[] args) {
    Node node5 = new Node(5, null, null);
    Node node4 = new Node(4, null, node5);
    Node node3 = new Node(3, null, null);
    Node node7 = new Node(7, null, null);
    Node node6 = new Node(6, null, node7);
    Node node2 = new Node(2, node3, node6);
    Node root = new Node(1, node4, node2);
    LinkedBinaryTree link = new LinkedBinaryTree(root);
    link.preTraversal();
    link.middleTraversal();
    link.postTraversal();
    System.out.print(link.getHeight());
    System.out.println(link.size());
    System.out.print("查找到的结点:"+link.findKey(6));
    link.preTraByStack();
    link.inOrderByStack();
    link.postTraByStack();
}

结果

前序遍历:1,4,5,2,3,6,7,
中序遍历:4,5,1,3,2,6,7,
后序遍历:5,4,3,7,6,2,1,
Tree的高度:4
树的大小:7
查找到的结点:Node{data=6, leftChild=null, rightChild=Node{data=7, leftChild=null, rightChild=null}}
通过队列实现遍历二叉树:1,4,2,5,3,6,7,
通过栈实现先序遍历二叉树:1,4,5,2,3,6,7,
通过栈实现中序遍历二叉树:4,5,1,3,2,6,7,
通过栈实现后序遍历二叉树:5,4,3,7,6,2,1,
posted @ 2020-10-16 15:08  深陈  阅读(128)  评论(0)    收藏  举报