算法导论里面第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 保护模式-系统加载-段寄存器