• 博客园logo
  • 会员
  • 周边
  • 新闻
  • 博问
  • 闪存
  • 众包
  • 赞助商
  • Chat2DB
    • 搜索
      所有博客
    • 搜索
      当前博客
  • 写随笔 我的博客 短消息 简洁模式
    用户头像
    我的博客 我的园子 账号设置 会员中心 简洁模式 ... 退出登录
    注册 登录

无信不立

  • 博客园
  • 联系
  • 订阅
  • 管理

公告

View Post

【算法和数据结构】漫画算法之树的遍历和二叉堆

一、树的遍历

树的的机构

   A

B     C

深度优先遍历顺序关注的是父节点的被遍历到的顺序。即A

  • 前序遍历的顺序:A,B,C
  • 中序遍历的顺序:B,A,C
  • 后续遍历的顺序:B,C,A

 

 

         A

    B         C

D     E   F     G

 

广度优先遍历(层序遍历)的遍历顺序为:A,B,C,D,E,F,G

 

示例中的树的

1、树的定义类

class TreeNode {
    private TreeNode leftTreeNode;
    private TreeNode rightTreeNode;
    private Integer nodeData;

    public TreeNode getLeftTreeNode() {
        return leftTreeNode;
    }

    public void setLeftTreeNode(TreeNode leftTreeNode) {
        this.leftTreeNode = leftTreeNode;
    }

    public TreeNode getRightTreeNode() {
        return rightTreeNode;
    }

    public void setRightTreeNode(TreeNode rightTreeNode) {
        this.rightTreeNode = rightTreeNode;
    }

    public Integer getNodeData() {
        return nodeData;
    }

    public void setNodeData(Integer nodeData) {
        this.nodeData = nodeData;
    }
}
View Code

2、树的遍历算法

import java.util.LinkedList;
import java.util.Queue;
import java.util.Stack;

public class TreeTraverseTest {


    public static void main(String[] args) {
        TreeNode treeNode = createTreeNode();
        //深度优先遍历测试
        //testDepthFirstTraversal(treeNode);
//        testDepthFirstTraversalByStack(treeNode);
        //广度优先遍历测试
        testBreadthFirstTraversal(treeNode);

    }


    /**
     * 递归实现深度优先遍历测试
     *
     * @param treeNode
     */
    public static void testDepthFirstTraversal(TreeNode treeNode) {
        //测试前序遍历,预期输出结果:1,2,3,4,5,6,7,8,9,10,11,12,13,14,15
        preOrderTraversalByRecursive(treeNode);

        //测试中序遍历,预期输出结果:4,3,5,2,7,6,8,1,11,10,12,9,14,13,15
        midOrderTraversal(treeNode);

        //测试后序遍历,预期输出结果:4,5,3,7,8,6,2,11,12,10,14,15,13,9,1
        afterOrderTraversal(treeNode);
    }


    /**
     * 利用栈进行深度优先遍历测试
     *
     * @param treeNode
     */
    public static void testDepthFirstTraversalByStack(TreeNode treeNode) {
        //测试前序遍历,预期输出结果:1,2,3,4,5,6,7,8,9,10,11,12,13,14,15
        preOrderTraversalByStack(treeNode);
        //测试中序遍历,预期输出结果:4,3,5,2,7,6,8,1,11,10,12,9,14,13,15
        midOrderTraversalByStack(treeNode);
        //测试后序遍历,预期输出结果:4,5,3,7,8,6,2,11,12,10,14,15,13,9,1
        afterOrderTraversalByStack(treeNode);
    }

    /**
     * 广度优先遍历测试
     *
     * @param treeNode
     */
    public static void testBreadthFirstTraversal(TreeNode treeNode) {
        //测试广度优先遍历,预期结果:1,2,9,3,6,10,13,4,5,7,8,11,12,14,15
        breadthFirstTraversalByQueue(treeNode);
    }


    public static TreeNode createTreeNode() {
        TreeNode node1 = new TreeNode();
        node1.setNodeData(1);
        TreeNode node2 = new TreeNode();
        node2.setNodeData(2);
        TreeNode node3 = new TreeNode();
        node3.setNodeData(3);
        TreeNode node4 = new TreeNode();
        node4.setNodeData(4);
        TreeNode node5 = new TreeNode();
        node5.setNodeData(5);
        TreeNode node6 = new TreeNode();
        node6.setNodeData(6);
        TreeNode node7 = new TreeNode();
        node7.setNodeData(7);
        TreeNode node8 = new TreeNode();
        node8.setNodeData(8);
        TreeNode node9 = new TreeNode();
        node9.setNodeData(9);
        TreeNode node10 = new TreeNode();
        node10.setNodeData(10);
        TreeNode node11 = new TreeNode();
        node11.setNodeData(11);
        TreeNode node12 = new TreeNode();
        node12.setNodeData(12);
        TreeNode node13 = new TreeNode();
        node13.setNodeData(13);
        TreeNode node14 = new TreeNode();
        node14.setNodeData(14);
        TreeNode node15 = new TreeNode();
        node15.setNodeData(15);

        node1.setLeftTreeNode(node2);
        node1.setRightTreeNode(node9);
        node2.setLeftTreeNode(node3);
        node2.setRightTreeNode(node6);
        node3.setLeftTreeNode(node4);
        node3.setRightTreeNode(node5);
        node6.setLeftTreeNode(node7);
        node6.setRightTreeNode(node8);
        node9.setLeftTreeNode(node10);
        node9.setRightTreeNode(node13);
        node10.setLeftTreeNode(node11);
        node10.setRightTreeNode(node12);
        node13.setLeftTreeNode(node14);
        node13.setRightTreeNode(node15);
        return node1;
    }

    /**
     * 深度优先遍历:前序遍历(递归)
     * 先打印树的根节点
     * 再打印树的左孩子节点
     * 最后打印树的右孩子节点
     *
     * @param treeNode
     */
    public static void preOrderTraversalByRecursive(TreeNode treeNode) {
        if (treeNode == null) {
            return;
        }
        //先打印当前节点的数据
        System.out.println(treeNode.getNodeData());
        //再打印当前节点的左节点的数据
        preOrderTraversalByRecursive(treeNode.getLeftTreeNode());
        //最后打印当前节点的右节点
        preOrderTraversalByRecursive(treeNode.getRightTreeNode());
    }

    /**
     * 深度优先遍历:前序遍历(栈)
     *
     * @param treeNode
     */
    public static void preOrderTraversalByStack(TreeNode treeNode) {
        Stack<TreeNode> stack = new Stack<>();
        Stack<TreeNode> mid = new Stack<>();
        TreeNode node = treeNode;
        while (node != null || !stack.isEmpty()) {
            //迭代访问节点的左孩子,并入栈
            while (node != null) {
                //打印根节点
                System.out.println(node.getNodeData());
                //将根节点入栈
                stack.push(node);
                //获取树的根节点的左节点
                node = node.getLeftTreeNode();
            }

            if (!stack.isEmpty()) {
                node = stack.pop();
                node = node.getRightTreeNode();
            }
        }
    }


    /**
     * 深度优先遍历:中序遍历
     * 先打印树的左孩子节点
     * 再打印树的根节点
     * 最后打印树的右孩子节点
     *
     * @param treeNode
     */
    public static void midOrderTraversal(TreeNode treeNode) {
        if (treeNode == null) {
            return;
        }
        //先打印左节点
        midOrderTraversal(treeNode.getLeftTreeNode());
        //再打印节点自身
        System.out.println(treeNode.getNodeData());
        //最后打印右节点
        midOrderTraversal(treeNode.getRightTreeNode());
    }

    /**
     * 中序遍历(stack)
     *
     * @param treeNode
     */
    public static void midOrderTraversalByStack(TreeNode treeNode) {
        Stack<TreeNode> stack = new Stack<>();
        TreeNode node = treeNode;
        while (node != null || !stack.isEmpty()) {
            while (node != null) {
                stack.push(node);
                node = node.getLeftTreeNode();
            }
            if (!stack.isEmpty()) {
                node = stack.pop();
                System.out.println(node.getNodeData());
                node = node.getRightTreeNode();
            }
        }
    }

    /**
     * 深度优先遍历:后序遍历
     * 先打印树的左孩子节点
     * 再打印树的右孩子节点
     * 最后打印树的根节点
     *
     * @param treeNode
     */
    public static void afterOrderTraversal(TreeNode treeNode) {
        if (treeNode == null) {
            return;
        }
        //先打印左节点
        afterOrderTraversal(treeNode.getLeftTreeNode());
        //再打印右节点
        afterOrderTraversal(treeNode.getRightTreeNode());
        //最后打印节点自身
        System.out.println(treeNode.getNodeData());
    }


    /**
     * 后序遍历(栈)
     * 如果当前弹栈的节点A,为栈里边的下一个节点B的左节点,表示左子树已经遍历完,当前节点为B节点的右孩子节点
     * 如果当前弹栈的节点为C,则表示右子树遍历完,当前节点应该为null,触发下一弹栈,弹出B节点
     *
     *==B
     *A   C
     * @param treeNode
     */
    public static void afterOrderTraversalByStack(TreeNode treeNode) {
        Stack<TreeNode> stack = new Stack<>();
        TreeNode node = treeNode;
        TreeNode temp = null;
        while (node != null || !stack.isEmpty()) {
            while (node != null) {
                stack.push(node);
                node = node.getLeftTreeNode();
            }
            while (!stack.isEmpty()) {
                 node = stack.pop();
                System.out.println(node.getNodeData());
                if(!stack.isEmpty()){
                    temp=stack.peek();
                }
                if(temp!=null&&temp.getLeftTreeNode()==node){
                    node=temp.getRightTreeNode();
                }else{
                    node=null;
                }
                temp=null;
            }
        }

    }

    /**
     * 广度优先遍历
     * @param treeNode
     */
    public static void breadthFirstTraversalByQueue(TreeNode treeNode) {
        Queue<TreeNode> queue = new LinkedList<>();
        queue.add(treeNode);
        while (!queue.isEmpty()) {
            TreeNode node = queue.poll();
            System.out.println(node.getNodeData());
            if (node.getLeftTreeNode() != null) {
                queue.add(node.getLeftTreeNode());
            }
            if (node.getRightTreeNode() != null) {
                queue.add(node.getRightTreeNode());
            }
        }
    }

}
View Code

3、树基于栈的遍历(前,中,后遍历)

/**
     * 后序遍历
     *
     * @param node
     */
    public static void traverseAfterByStack(Node node) {

        Stack<Node> stack = new Stack<>();
        Node node1 = node;

        while (node1 != null || !stack.isEmpty()) {

            while (node1 != null) {
                stack.add(node1);
                node1 = node1.left;
            }

            Node node2 = stack.peek();
            //读出节点是父亲的左孩子节点
            if (node2.parent != null && node2.parent.left == node2) {
                System.out.println(node2.v);
                stack.pop();
                node1 = stack.peek() != null ? stack.peek().right : null;

            } else {
                System.out.println(node2.v);
                stack.pop();
                node1 = null;
            }

        }

    }


    /**
     * 中序遍历
     *
     * @param node
     */
    public static void traverseMindByStack(Node node) {
        Stack<Node> stack = new Stack<>();
        Node node1 = node;

        while (node1 != null || !stack.isEmpty()) {

            while (node1 != null) {
                stack.add(node1);
                node1 = node1.left;
            }


            Node node2 = stack.pop();
            System.out.println(node2.v);
            node1 = node2.right;
        }
    }


    /**
     * 前序遍历基于栈
     *
     * @param node
     */
    public static void traversBeforeByStack(Node node) {
        Stack<Node> stack = new Stack<>();

        Node node1 = node;
        //先打印前序节点,并将节点压入栈中。当节点的left孩子为空时,退出压栈动作
        while (node1 != null || !stack.isEmpty()) {

            //将节点压入栈中
            while (node1 != null) {
                System.out.println(node1.v);
                stack.push(node1);
                node1 = node1.left;
            }


            //从栈中读取数据
            Node node2 = stack.pop();
            node1 = node2.right;

        }

    }
View Code

4、二叉树的左视图 和 右视图

 /**
     * 构建一棵树
     *
     * @return
     */
    public static Node buildNode() {
        Node node = new Node("A");
        Node node1 = new Node("B");
        Node node2 = new Node("C");
        Node node3 = new Node("D");
        Node node4 = new Node("E");
        Node node5 = new Node("F");
        Node node6 = new Node("G");
        Node node7 = new Node("H");

        node.left = node1;
        node.right = node2;
        node1.parent = node;
        node2.parent = node;

        node1.left = node3;
        node1.right = node4;
        node3.parent = node1;
        node4.parent = node1;

        node2.left = node5;
        node2.right = node6;
        node5.parent = node2;
        node6.parent = node2;

        node3.left = node7;
        node7.parent = node3;

        return node;
    }


    /**
     * 二叉树的左视图:相等于层序遍历,每一层的第一个节点。
     * 基于两个队列,进行交换,来保存每一层树的节点,从而能读到每层的第一个节点,就是左视图的结果
     *
     * @param node
     * @return
     */
    public static List<String> leftView(Node node) {

        Queue<Node> nodeQueue1 = new LinkedList<>();
        Queue<Node> nodeQueue2 = new LinkedList<>();
        List<String> result = new ArrayList<>();

        nodeQueue1.add(node);
        boolean isFirst = true;
        while (nodeQueue1.size() != 0) {
            Node node1 = nodeQueue1.poll();

            if (isFirst) {
                result.add(node1.v);
                isFirst = false;
            }

            if (node1.left != null) {
                nodeQueue2.add(node1.left);
            }

            if (node1.right != null) {
                nodeQueue2.add(node1.right);
            }



            if (nodeQueue1.isEmpty()) {
                isFirst=true;
                Queue<Node> tmp = nodeQueue1;
                nodeQueue1 = nodeQueue2;
                nodeQueue2 = tmp;
            }
        }
        return result;

    }

    /**
     * 二叉树的右视图:相等于层序遍历,每一层的最后一个节点。
     * 基于两个队列,进行交换,来保存每一层树的节点,从而能读到每层的最后一个节点,就是右视图的结果
     *
     * @param node
     * @return
     */
    public static List<String> rightView(Node node) {

        Queue<Node> nodeQueue1 = new LinkedList<>();
        Queue<Node> nodeQueue2 = new LinkedList<>();
        List<String> result = new ArrayList<>();

        nodeQueue1.add(node);


        while (nodeQueue1.size() != 0) {
            Node node1 = nodeQueue1.poll();

            if (node1.left != null) {
                nodeQueue2.add(node1.left);
            }

            if (node1.right != null) {
                nodeQueue2.add(node1.right);
            }

            if (nodeQueue1.isEmpty()) {
                result.add(node1.v);
                Queue<Node> tmp = nodeQueue1;
                nodeQueue1 = nodeQueue2;
                nodeQueue2 = tmp;
            }
        }
        return result;

    }
View Code

5、二叉树的俯视图 和 仰视视图

/**
     * 树的仰视图
     * @param node
     * @return
     */
    public static void upView(Node node,List<String> result){
        if(node==null){
            return ;
        }
        if(node.left==null && node.right==null){
            result.add(node.v);
            return ;
        }
        upView(node.left,result);
        upView(node.right,result);
    }


    /**
     * 树的俯视图
     * @param node
     * @return
     */
    public static List<String> topView(Node node) {

        List<String> result = new ArrayList<>();

        if (node == null) {
            return result;
        }
        //添加根节点
        result.add(node.v);

        Node left = node.left;
        Node right = node.right;

        while (left != null || right != null) {

            if (left != null) {
                result.add(left.v);
                left = left.left;
            }

            if (right != null) {
                result.add(right.v);
                right = right.right;
            }
        }

        return result;

    }
View Code

 

二、二叉堆

1、二叉堆的向上调整,向下调整,构建二叉堆

package com.spring.test.service.algorithm.tree;

import java.util.Arrays;

/**
 * 二叉堆的公式:
 * 已知父节点下标,求子节点小标
 * leftChildIndex=parentIndex*2+1
 * rightChildIndex=parentIndex*2+2
 *
 * 已知子节点下标(不分左右),求父亲节点下标
 * parentIndex=(childIndex-1)/2
 *
 *
 * 本示例演练的为最小堆
 *
 * @author shangxiaofei
 * @date 8:09 PM 2019/6/2
 */
public class BinaryTreeHeap {

    /**
     * 节点上浮
     *
     * @param array      待调整的二叉堆
     * @param treeLength 二叉堆的大小
     */
    public static void upAdjust(int[] array, int treeLength) {
        //最后一个子节点的下标
        int childIndex = treeLength - 1;
        //计算它的父节点的下标
        int parentIndex = (childIndex - 1) / 2;
        //赋值需要上浮的节点的值
        int temp = array[childIndex];
        //开始上浮,孩子节点为0,代表已经到了堆顶
        while (childIndex > 0 && array[parentIndex] > temp) {
            //父节点和子节点进行交换
            array[childIndex] = array[parentIndex];
            //赋值新的孩子节点
            childIndex = parentIndex;
            //计算新的父节点
            parentIndex = (childIndex - 1) / 2;
        }
        //将上浮节点赋值给新的孩子节点
        array[childIndex] = temp;
    }

    /**
     * 节点下沉
     *
     * @param array       待调整的二叉堆
     * @param parentIndex 要下沉的父节点的下标
     * @param treeLength  二叉堆的大小
     */
    public static void downAdjust(int[] array, int parentIndex, int treeLength) {
        //先求出该父节点的左孩子节点的下标
        int childIndex = parentIndex * 2 + 1;
        //待调整的数
        int temp = array[parentIndex];
        //开始下沉,当孩子节点的下标小于树的长度时,表示还未到树的最后一个节点
        while (childIndex < treeLength) {
            if (childIndex + 1 < treeLength && array[childIndex] > array[childIndex + 1]) {
                //如果存在右孩子节点,且左孩子节点大于右孩子节点,则待下沉节点应该与右孩子节点进行比较
                childIndex++;
            }
            //如果待调整父节点,大于最小孩子节点,则进行位置替换
            if (temp > array[childIndex]) {
                array[parentIndex] = array[childIndex];
                //更新当前孩子节点为parentIndex
                parentIndex = childIndex;
                //计算最新的parentIndex节点的最新左孩子节点
                childIndex = parentIndex * 2 + 1;
                //继续比较孩子节点
                continue;
            }
            //下沉节点已经找到合适的位置,这个位置均小于左孩子和右孩子
            break;
        }
        array[parentIndex] = temp;
    }

    /**
     * 构建二叉堆
     *
     * @param array 要调整的普通数组,元素是满的
     */
    public static void bulidBinaryHeap(int[] array) {
        for (int i = (array.length - 2) / 2; i >= 0; i--) {
            downAdjust(array, i, array.length);
        }
    }


    public static void main(String[] args) {
        int[] heap = new int[]{7, 9, 4, 5, 8, 9, 10};
        //构建二叉堆
        bulidBinaryHeap(heap);
        System.out.println("待调整后的二叉堆为:" + Arrays.toString(heap));
        //待调整后的二叉堆为:[4, 5, 7, 9, 8, 9, 10]

        int[] heap1 = new int[]{4, 5, 7, 9, 8, 9, 10, 0};
        //向上调整
        upAdjust(heap1, heap1.length);
        System.out.println("向上调整后的堆为:" + Arrays.toString(heap1));
        //向上调整后的堆为:[0, 4, 7, 5, 8, 9, 10, 9]

        int[] heap2 = new int[]{10, 4, 5, 7, 9, 8};
        downAdjust(heap2, 0, heap2.length);
        System.out.println("向下调整后的堆为:" + Arrays.toString(heap2));
        //向下调整后的堆为:[4, 7, 5, 10, 9, 8]

    }
}
View Code

2、二叉堆数据结构

package com.sxf.study.interview.tree;

import java.util.PriorityQueue;

/**
 * @date 3:49 PM 2020/2/1
 */
public class BinaryHeapTest {

    /**
     * 二叉堆的公式
     * 已知父亲节点的下标,求子节点下标
     * leftIndex=2*parentIndex+1
     * rightIndex=2*parentIndex+2
     *
     * 已知孩子节点的下标,求父亲节点的下标
     * parentIndex=(childIndex-1)/2
     *
     * 加入一个节点:
     * 加入数组的最后一个元素,向上调整(已知孩子节点坐标,和父亲节点比较)
     *
     * 取出一个节点:
     * 取最顶节点,返回结果。将最尾部的元素放置在数组的头部,向下调整。(已知父亲节点坐标,和孩子元素进行对比)
     *
     * @param args
     */
    public static void main(String[] args) {

        PriorityQueue<Integer> priorityQueue = new PriorityQueue<>();
        priorityQueue.add(1);
        priorityQueue.poll();

    }


}


/**
 * ==========1
 * ======2     3
 * ===4    5 6   7
 */
class BinaryHead {

    private Object[] node = new Object[10];

    private int nodeSize;

    /**
     * 添加一个节点
     *
     * @param data
     */
    public void push(String data) {
        //step1:元素为空,则抛出异常
        if (data == null) {
            throw new IllegalArgumentException("入参异常");
        }
        //step2:如果为第一个元素,则无需排序
        if (nodeSize == 0) {
            node[0] = data;
            nodeSize++;
            return;
        }
        //判断元素的个数>=数组的长度,则需要扩容(本示例不扩容,忽略默认数组长度够用)

        //step3:开始向上调整
        //当前数组最后一个空的下标位置
        int childIndex = nodeSize;
        nodeSize++;
        siftUp(childIndex,data);
    }

    /**
     * 向上调整
     * @param index
     * @param data
     */
    private void siftUp(int index, Object data) {
        Comparable dataComparable = (Comparable) data;
        //获取该位置的孩子节点的父亲节点的位置
        while (index > 0) {
            int parentIndex = (index - 1) / 2;
            Comparable parentData = (Comparable) node[parentIndex];
            //孩子节点大于等于父亲节点,则无需进行调整
            if (dataComparable.compareTo(parentData) >= 0) {
                break;
            }
            //孩子节点的数据小于父亲节点=>父亲节点和孩子节点进行位置替换,
            node[index]=parentData;
            index=parentIndex;
        }
        node[index] = dataComparable;
    }


    /**
     * 弹出1个节点
     *
     * @return
     */
    public String poll() {
        //step1:当个数为0,返回null
        if(nodeSize==0){
            return null;
        }
        //step2:取出最小的元素
        String result= (String) node[0];
        //step3:元素个数减少1个,并得到最后一个元素,将最后一个元素的位置设置为null
        nodeSize--;
        int lastNodeIndex=nodeSize;
        Object lastNode=node[lastNodeIndex];
        node[lastNodeIndex]=null;
        //step4:向下调整
        siftDown(0,lastNode);
        return result;
    }

    /**
     * 向下调整
     * @param index
     * @param data
     */
    private void siftDown(int index,Object data){
        Comparable dataComparable= (Comparable) data;
        //获取最后1个没有孩子下标的元素,最后比较的临界值
        int lastParentIndex=nodeSize/2;
        while (index<lastParentIndex){
            //左孩子节点的位置
            int leftChildIndex=index*2+1;
            //右孩子节点的位置
            int rightChildIndex=leftChildIndex+1;

            //待调整元素和其两个孩子中最小的元素进行比较(最起码有左孩子,但不一定有右孩子)
            int comparableChildIndex=leftChildIndex;
            Comparable comparableChildData= (Comparable) node[leftChildIndex];

            //如果存在右孩子,则在两个孩子中找到最小的那个元素进行比较
            if(rightChildIndex<nodeSize&&comparableChildData.compareTo(node[rightChildIndex])>0){
                //左孩子大于右孩子,则和右孩子进行比较
                comparableChildIndex=rightChildIndex;
                comparableChildData= (Comparable) node[comparableChildIndex];
            }

            if(dataComparable.compareTo(comparableChildData)<=0){
                //如果待调整元素小于其孩子节点
                break;
            }

            //将小的元素上浮
            node[index]=comparableChildData;
            //待比较的位置下沉
            index=comparableChildIndex;
        }
        node[index]=dataComparable;
    }
}
View Code

3、将一个数组(数组的每一个下标都存在数据)调整为二叉堆

/**
     * 构建最小堆
     * 将一个普通数组构建成二叉堆
     * 法则:从一个数组中的最后一个父亲节点开始,对每一个父亲节点一次做下沉操作,调整到数组的头节点
     * @param objects
     */
    public static void buildBinaryHeap(Object[] objects){
        int length=objects.length;
        int lastIndex=length-1;
        //最后一个父亲节点
        int lastParentIndex=(lastIndex-1)/2;
        //从最后1个父亲节点依次向下调整,直到调整至数组的头节点,调整完毕,二叉堆就形成了
        for(int i=lastIndex;i>=0;i--){
            siftDownArray(objects,i,length);
        }
    }

    public static void siftDownArray(Object[] objects,int lastParentIndex,int dataSize){
        //要调整的数据
        Comparable comparableData= (Comparable) objects[lastParentIndex];
        //要调整的元素下标小于数组长度
        while (lastParentIndex<dataSize){
            int childIndex=lastParentIndex*2+1;
            Comparable comparableChildData= (Comparable) objects[childIndex];
            int rightChildIndex=childIndex+1;
            if(rightChildIndex<dataSize && comparableChildData.compareTo(objects[rightChildIndex])>0){
                //左右孩子节点比较,找出最小的的子节点
                childIndex=rightChildIndex;
                comparableChildData= (Comparable) objects[childIndex];
            }

            //如果比较的节点小于或等于孩子节点,则终止调整
            if(comparableData.compareTo(comparableChildData)<=0){
                break;
            }
            objects[lastParentIndex]=comparableChildData;
            lastParentIndex=childIndex;
        }
        objects[lastParentIndex]=comparableData;
    }
View Code

 

posted on 2019-06-02 22:01  无信不立  阅读(306)  评论(0)    收藏  举报

刷新页面返回顶部
 
博客园  ©  2004-2026
浙公网安备 33010602011771号 浙ICP备2021040463号-3