assill 2015-10-26 03:56 采纳率: 18.2%
浏览 1992

算法导论堆排序基础问题

算法导论里面第6章,堆排序。习题6.1-2,含有n个元素的堆的高度的求解。。是不是把根那一行算作第0行了??有第0刚这么一说吗?不都是从第一行起的吗?

  • 写回答

1条回答 默认 最新

  • havedream_one 2015-10-26 05:18
    关注
     public static void heapSort(int arr[]){
            //初始化堆
            initHeap(arr);
            //System.out.println("初始化堆:" + Arrays.toString(arr));
            //end表示堆的结束位置
            int end = arr.length - 1;
            while(end > 0){
                //删除堆顶元素
                int temp = arr[0];
                arr[0] = arr[end];
                arr[end] = temp;
                end--;
                if(end > 0){
                    //调整堆
                    adjustHeap(arr,end);
                }
            }
        }
        public static void initHeap(int[] arr){
            //从0计数,则位置i的节点,左孩子在位置2i+1处,右孩子在位置2i+2处,而父节点在(i-1)/2处
            for(int i = 1 ; i < arr.length ; i ++){
                int current = i;
                while(current > 0){
                    int parent = (current - 1) / 2;
                    //孩子节点大于父节点,则交换位置
                    if(arr[current] > arr[parent]){
                        int temp = arr[current];
                        arr[current] = arr[parent];
                        arr[parent] = temp;
                        //向上调整,跟新current
                        current = parent;
                    }else{
                        break;
                    }
                }
            }
        }
        public static void adjustHeap(int[] arr,int end){
            //删除堆顶元素后,调整堆顶的位置
            //需要知道的是,由于删除堆顶只是调整了堆顶的元素值,
            //因此除去堆顶之后,左右都是符合堆的树,
            //如此将堆顶元素向下调整的时候,如果检测到堆顶元素符合堆的定义时,
            //而由于它的左右子树始终是符合堆的定义,因此调整过程可以结束
            int current = 0;
            while(current < end){   
                int left = current * 2 + 1;
                int right = current * 2 + 2;
                if(left <= end && right <= end){
                    //左右节点都存在
                    if(!(arr[current] >= arr[left] && arr[current] >= arr[right])){
                        //需要进行调整堆顶
                        int index = left;
                        if(arr[left] < arr[right]){
                            //左节点小于右节点
                            index = right;
                        }
                        int temp = arr[current];
                        arr[current] = arr[index];
                        arr[index] = temp;
                        current = index;
                    }else{
                        //此时已经是堆了,无需继续向下调整
                        break;
                    }
                }else if(left <= end && right > end){
                    //左节点存在但右节点不存在  
                    if(arr[current] < arr[left]){
                        int temp = arr[current];
                        arr[current] = arr[left];
                        arr[left] = temp;
                        current = left;
                    }else{
                        //此时已经是堆了,无需继续向下调整
                        break;
                    }
                }else{
                    //左右节点都不存在,已经调整到底了
                    break;
                }
            }
        }
    
    评论

报告相同问题?

悬赏问题

  • ¥15 素材场景中光线烘焙后灯光失效
  • ¥15 请教一下各位,为什么我这个没有实现模拟点击
  • ¥15 执行 virtuoso 命令后,界面没有,cadence 启动不起来
  • ¥50 comfyui下连接animatediff节点生成视频质量非常差的原因
  • ¥20 有关区间dp的问题求解
  • ¥15 多电路系统共用电源的串扰问题
  • ¥15 slam rangenet++配置
  • ¥15 有没有研究水声通信方面的帮我改俩matlab代码
  • ¥15 ubuntu子系统密码忘记
  • ¥15 保护模式-系统加载-段寄存器