数据结构-二叉树(全)

文章目录

简介

下面包括大量的二叉树的数据结构算法,包括各种遍历,深度计算,创建二叉树等等,且几乎都有递归和非递归的实现手段

Java 实现

// 结点
class Node {
    int data;
    Node left = null;
    Node right = null;
}

// 二叉树
public class BinaryTree {
    // 根结点
    private Node root;
    // 输入的数组
    private int[] arr_in;
    // 输出的数组
    private int[] arr_out;
    // 记录数组下标
    private static int index;
    
    // 初始化
    public BinaryTree(int[] arr) {
        root = new Node();
        this.arr_in = arr;
        arr_out = new int[arr.length];
        index = 0;
    }
    
    // 根据先序遍历和中序遍历创建二叉树
    public Node createByPreAndIn(int[] preArr, int[] inArr) {
        if (preArr.length > 0) {
            Node node = new Node();
            node.data = preArr[0];
            int i;
            for (i = 0; preArr[0] != inArr[i]; i++) ;
            // 中序左子树
            int[] leftInArr = new int[i];
            // 中序右子树
            int[] rightInArr = new int[inArr.length - i - 1];
            // 先序左子树
            int[] leftPreArr = new int[i];
            // 先序右子树
            int[] rightPreArr = new int[inArr.length - i - 1];
            System.arraycopy(inArr, 0, leftInArr, 0, leftInArr.length - 1);
            System.arraycopy(inArr, i + 1, rightInArr, 0, rightInArr.length - 1);
            System.arraycopy(preArr, 1, leftPreArr, 0, leftPreArr.length - 1);
            System.arraycopy(preArr, i + 1, rightInArr, 0, rightPreArr.length - 1);
            node.left = createByPreAndIn(leftPreArr, leftInArr);
            node.right = createByPreAndIn(rightPreArr, rightInArr);
            return node;
        }
        else
            return null;
    }

    // 根据中序遍历和后序遍历创建二叉树
    public Node createByInAndPost(int[] inArr, int[] postArr) {
        if (inArr.length > 0) {
            Node node = new Node();
            node.data = postArr[postArr.length];
            int i;
            for (i = 0; postArr[postArr.length] != inArr[i]; i++) ;
            // 中序左子树
            int[] leftInArr = new int[i];
            // 中序右子树
            int[] rightInArr = new int[inArr.length - i - 1];
            // 后序左子树
            int[] leftPostArr = new int[i];
            // 后序右子树
            int[] rightPostArr = new int[inArr.length - i - 1];
            System.arraycopy(inArr, 0, leftInArr, 0, leftInArr.length - 1);
            System.arraycopy(inArr, i + 1, rightInArr, 0, rightInArr.length - 1);
            System.arraycopy(postArr, 0, leftPostArr, 0, leftPostArr.length - 1);
            System.arraycopy(postArr, i, rightPostArr, 0, rightPostArr.length - 1);
            node.left = createByInAndPost(leftInArr, leftPostArr);
            node.right = createByInAndPost(rightInArr, rightPostArr);
            return node;
        }
        else
            return null;
    }
    
    // 先序遍历二叉树(递归)根→左→右
    public int[] preorderTraversalRecursion(Node r) {
        if (r) {
            arr_out[index++] = r.data;
            preorderRecursion(r.left, index);
            preorderRecursion(r.rigth, index);
        }
        if (index == arr_in.length)
            index = 0;
        return arr_out;
    }
    // 先序遍历二叉树(非递归)根→左→右
    public int[] preorderTraversal(Node r) {
        Stack stack = new Stack();
        Node node = r;
        while (!stack.empty() || node) {
            if (node) {
                stack.push(node);
                // 根
                arr_out[index++] = node.data;
                // 左
                node = node.left;
            }
            else {
                Node top = stack.pop();
                // 右
                node = top.right;
            }
        }
        index = 0;
        return arr_out;
    }
    
    // 中序遍历二叉树(递归)左→根→右
    public int[] inorderTraversalRecursion(Node r) {
        if (r) {
            inorderRecursion(r.left, index);
            arr_out[index++] = r.data;
            inorderRecursion(r.rigth, index);
        }
        if (index == arr_in.length)
            index = 0;
        return arr_out;
    }
    // 中序遍历二叉树(非递归)左→根→右
    public int[] inorderTraversal(Node r) {
        Stack stack = new Stack();
        Node node = r;
        while (!stack.empty() || node) {
            if (node) {
                stack.push(node);
                // 左
                node = node.left;
            }
            else {
                Node top = stack.pop();
                // 根
                arr_out[index++] = top.data;
            	// 右
                node = top.right;
            }
        }
        index = 0;
        return arr_out;
    }
    
    // 后序遍历二叉树(递归)左→右→根
    public int[] postorderTraversalRecursion(Node r) {
        if (r) {
            postorderRecursion(r.left, index);
            postorderRecursion(r.rigth, index);
            arr_out[index++] = r.data;
        }
        if (index == arr_out.length)
            index = 0;
        return arr_out;
    }
    // 后序遍历二叉树(非递归)左→右→根
    public int[] postorderTraversal(Node r) {
        Stack stack = new Stack();
        Node node = r;
        Node top;
        while (!stack.empty() || node) {
            if (node) {
                stack.push(node);
                // 左
                node = node.left;
            }
            else {
                if (stack.peek().right != null && stack.peek().right != top)
                    // 右
                    node = stack.peek().right;
                else {
                    top = stack.pop();
                    // 根
                    arr_out[index++] = top.data;
                    node = stack.peek();
                }
            }
        }
        index = 0;
        return arr_out;
    }
    
    // 层次遍历二叉树(递归)
    public int[] levelTraversalRecursion(ArrayList al) {
        ArrayList arrayList = new ArrayList();
        for(Node n : al) {
            arr_out[index++] = n.data;
            if (n.left)
                arrayList.add(n.left);
            if (n.right)
                arrayList.add(n.right);
        }
        if(!arrayList.isEmpty())
        	levelTraversalRecursion(arrayList);
        if(index == arr_out.length)
            index = 0;
        return arr_out;
    }
    
    // 层次遍历二叉树
    public int[] levelTraversal(Node r) {
        if(r == null)
            return null;
        else {
            Queue queue = new LinkedList();
            Node node = r;
            queue.add(node);
            while(!LinkedList.isEmpty()) {
                Node top = queue.remove();
                arr_out[index++] = top.data;
                if (top.left)
                    queue.add(top.left);
                if (top.right)
                    queue.add(top.right);
            }
            index = 0;
            return arr_out;
        }
    }
    
    // 先序复制二叉树(递归)根→左→右
    public Node preorderCopyRecursion(Node r, Node n) {
        if (r) {
            n = new Node();
            n = r.data;
            preorderCopyRecursion(r.left, n.left);
            preorderCopyRecursion(r.right, n.right);
        }
        else
            n = null;
        return n;
    }
    
    // 先序复制二叉树(非递归)根→左→右
    public Node preorderCopy(Node r, Node n) {
        Stack rStack = new Stack();
        Stack nStack = new Stack();
        Node rNode = r;
        Node nNode = n;
        while (rNode || !rStack.empty()) {
            if (rNode) {
                rStack.push(rNode);
                nNode = new Node();
                nStack.push(nNode);
                // 根
                nNode.data = rNode.data;
                // 左
                rNode = rNode.left;
                nNode = nNode.left;
            }
            else {
                Node rTop = rStack.pop();
                Node nTop = nStack.pop();
                // 右
                rNode = rTop.right;
                nNode = nTop.right;
            }
        }
        return n;
    }
    
    // 中序复制二叉树(递归)左→根→右
    public Node inorderCopyRecursion(Node r, Node n) {
        if (r) {
            inorderCopyRecursion(r.left, n.left);
            n = new Node();
            n = r.data;
            inorderCopyRecursion(r.right, n.right);
        }
        else
            n = null;
        return n;
    }
    
    // 中序复制二叉树(非递归)左→根→右
    public Node inorderCopy(Node r, Node n) {
        Stack rStack = new Stack();
        Stack nStack = new Stack();
        Node rNode = r;
        Node nNode = n;
        while (rNode || !rStack.empty()) {
            if (rNode) {
                rStack.push(rNode);
                nNode = new Node();
                nStack.push(nNode);
                // 左
                rNode = rNode.left;
                nNode = nNode.left;
            }
            else {
                Node rTop = rStack.pop();
                Node nTop = nStack.pop();
                // 根
                nTop.data = rTop.data;
                // 右
                rNode = rNode.right;
                nNode = nNode.right;
            }
        }
        return n;
    }
    
    // 后序复制二叉树(递归)左→右→根
    public Node postorderCopyRecursion(Node r, Node n) {
        if (r) {
            postorderCopyRecursion(r.left, n.left);
            postorderCopyRecursion(r.right, n.right);
            n = new Node();
            n = r.data;
        }
        else
            n = null;
        return n;
    }
    
    // 后序复制二叉树(非递归)左→右→根
    public Node postorderCopy(Node r, Node n) {
        Stack rStack = new Stack();
        Stack nStack = new Stack();
        Node rNode = r;
        Node nNode = n;
        Node rTop;
        Node nTop;
        while (rNode || !rStack.empty()) {
            if (rNode) {
                rStack.push(rNode);
                rNode = new Node();
                rStack.push(rNode);
                // 左
                rNode = rNode.left;
                nNode = nNode.left;
            }
            else {
                if (rStack.peek().right != null && rStack.peek().right != rTop) {
                    // 右
                    rNode = rNode.right;
                    nNode = nNode.right;
                }
                else {
                    rTop = rStack.pop();
                    nTop = nStack.pop();
                    // 根
                    nTop.data = rTop.data;
                    rNode = rStack.peek();
                    nNode = nStack.peek();
                }
            }
        }
        return n;
    }
    
    // 得到二叉树根结点
    public Node getRoot() {
        return root;
    }
    
    // 二叉树深度(递归)
    public int getDepthRecursion(Node r) {
        if (r) {
            int m = getDepthRecursion(r.left);
            int n = getDepthRecursion(r.right);
            return (m>=n)?(m+1):(n+1);
        }
        else
            return 0;
    }
    
    // 二叉树深度(非递归)
    public int getDepth(Node r) {
        Stack stack = new Stack();
        Node node = r;
        Node top;
        int depth = 0;
        int maxDepth = 0;
        while(node || !stack.empty()) {
            if (node) {
                stack.push(node);
                depth++;
                if (depth > maxDepth)
                    maxDepth = depth;
                node = node.left;
            }
            else {
                if (stack.peek().right && stack.peek().right != top)
                    node = stack.peek().right();
                else {
                    top = stack.pop();
                    depth--;
                    node = stack.peek();
                }
            }
        }
        return maxDepth;
    }
    
    // 得到二叉树结点的个数(递归)
    public int getNodesNumber(Node r) {
        if (r)
            return getNodesNumber(r.left) + getNodesNumber(r.right) + 1;
        else
            return 0;
    }
    
    // 得到二叉树结点的个数(非递归)
    public int getNodesNumber(Node r) {
        Stack stack = new Stack();
        Node node = r;
        int count = 0;
        if (node) {
            stack.push(node);
            count++;
            node = node.left
        }
        else {
            Node top = stack.pop();
            node = top.right;
        }
        return count;
    }
    
    // 得到二叉树叶子结点的个数(递归)
    public int getLeafCountRecursion(Node r) {
        if (r.left == null && r.right == null)
            return 1;
        else
        	return getLeafCountRecursion(r.left) + getLeafCountRecursion(r.right);
    }
    
    // 得到二叉树叶子结点的个数(非递归)
    public int getLeafCount(Node r) {
        Stack stack = new Stack();
        Node node = r;
        int leaf = 0;
        while (r || !stack.empty()) {
            if (r.left != null || r.right != null) {
                stack.push(node);
                node = r.left;
            }
            else {
                leaf++;
                node = stack.pop().right;
            } 
        }
        return leaf;
    }
    
    // 得到二叉树非叶子结点的个数(递归)
    public int getNonleafCountRecursion(Node r) {
        // 左右两个结点都是 null,此结点必为叶子
        if (r.left == null && r.right == null)
            return 0;
        else
            return getNonleafCount(r.left) + getNonleafCount(r.right) + 1;
    }
    
    // 得到二叉树非叶子结点的个数(非递归)
    public int getNonleafCount(Node r) {
        Stack stack = new Stack();
        Node node = r;
        int nonleaf = 0;
        while (node || !stack.empty()) {
            if (node.left != null || node.right != null) {
                stack.push(node);
                nonleaf++;
                node = node.left;
            }
            else
                node = stack.pop().right;
        }
        return nonleaf;
    }
}
发布了197 篇原创文章 · 获赞 62 · 访问量 7万+

猜你喜欢

转载自blog.csdn.net/abcnull/article/details/104507611