首页 > 试题广场 >

将整数数组(7-6-3-5-4-1-2)按照堆排序的方式原地

[单选题]
将整数数组(7-6-3-5-4-1-2)按照堆排序的方式原地进行升序排列,请问在整个排序过程中,元素3的数组下标发生过____次改变。
  • 0
  • 1
  • 2
  • 3
  • 4
  • 5
大根堆来排序,则只需要2次移动3的下标,第一次在将3升到堆顶的时候,第二次则是将3与末尾元素交换的时候,
不知道答案的3从何而来。
考虑小根堆来排序,则需要4次:将原数组转化为一个小根堆,进而进行堆排序操作:
1.首先对原排序进行小根堆转换,则由(7,6,3,5,4,1,2)【大根堆】建立小根堆:
(7,6,3,5,4,1,2)->(7,6,1,5,4,3,2)->(7,4,1,5,6,3,2)->(1,4,7,5,6,3,2)->【下沉】(1,4,2,5,6,3,7)   ,可见3的下标移动1次;
2.堆排序开始,先将堆顶元素与末尾调换,去除末尾元素后,对剩下的堆进行调整:
(1,4,2,5,6,3,7)->(7,4,2,5,6,3,1)->【去除末元素,用x占位之前的移除元素,不参与调整】(7,4,2,5,6,3,x)->
【调整开始】(2,4,7,5,6,3,x)->(2,4,3,5,6,7,x),可见3的下标又移动1次;
3.对堆顶与末尾元素调换,继续采用2的策略进行调整:
(2,4,3,5,6,7,x)->(7,4,3,5,6,2,x)->【去除末元素,用x占位之前的移除元素,不参与调整】(7,4,3,5,6,x,x)->
【调整开始】(3,4,7,5,6,x,x),可见3的下标再次移动1次;
4.如果采用标准的堆排序策略,还需要将3与末尾元素交换,即(3,4,7,5,6,x,x)->(6,4,7,5,3,x,x)->...3的下标再移动一次。
编辑于 2015-08-25 15:30:48 回复(5)
排序是对一个数组而言,并不需要输出,也就是说,给一个乱序的数组,经过排序后,这个数组是升序的(一个数组就可以实现堆排序),如果要输出的话,直接把这个数组输出来就可以了。
即:如果需要升序排列,则要逐步大顶堆。因为根节点被一个个放在后面去了。降序排列则要建立小顶堆。
public class HeapOperate2 {
	/*
	 * 建立堆时只需要保证根结点小于两个子结点或者大于两个子结点,对两个子结点大小没有要求
	 */

	public static void main(String[] args) {
		int[] a = { 9, 8, 7, 6, 5, 4, 3, 2, 1, 0, -1, -2, -3 };  
		//在堆排序之前,打印初始数组
        print(a);  
        //进行堆排序
        heapSort(a);  
        //进行堆排序之后
        print(a);  
	}
	

	public static void heapSort(int[] a){
		//建立大根堆
        buildMaxHeap(a);  
        for (int i = a.length - 1; i >= 1; i--) {  
            swap(a[0], a[i]);  
            maxHeap(a, i, 0);  
        }  
    }  

    private static void buildMaxHeap(int[] a) {  
        int half = a.length/2;  
        for (int i = half; i >= 0; i--) {  
            maxHeap(a, a.length, i);  
        }  
    }  

    private static void maxHeap(int[] a, int heapSize, int index) {  
    	//找出index位置处左右孩子的位置left和right
        int left = index * 2 + 1;  
        int right = index * 2 + 2;  

        int largest = index;  
        if (left < heapSize && a[left] > a[index]) {  
            largest = left;  
        }  

        if (right < heapSize && a[right] > a[largest]) {  
            largest = right;  
        }  

        if (index != largest){
        	//交换两个数据
            swap(a[index], a[largest]);  
            maxHeap(a, heapSize, largest);  
        }  
}
}

谢谢大家支持!
编辑于 2016-06-13 16:06:36 回复(0)
变了两次,2变为0,0又变为2
发表于 2015-10-10 11:53:39 回复(0)
题目原地进行升序排序,意思是对数组进行堆排序后,数组由(7-6-3-5-4-1-2)变成 (1-2-3-4-5-6-7)。
因为大根堆每进行一次排序,都把当前根节点与最右后叶子节点交换,因此最大元素放到数组末尾,所以是指构建更新大根堆。
发表于 2015-08-27 10:03:42 回复(0)
按照升序排列是建小根堆的过程
发表于 2015-08-25 17:40:22 回复(0)
3的位置没发生改变吧
发表于 2015-08-24 22:25:31 回复(0)
注:粉红色代表已经排好序的,绿色代表交换的节点,砖红色代表没做改动的店
从图中可以看出来,3在交换4和交换5这两步中,位置都有变化,所以一共是2次
注意交换4这一步,本来交换之后,就是有序的,但是程序还会继续调整,直到所有节点调整完毕
发表于 2017-07-04 08:54:40 回复(4)
Ze头像 Ze
按整数数组的最大堆定义,每次调整完后根结点的元素与最后个元素交换,继续下次调整,直到所有的结点调整完毕。
原数组为 7 6 3 5 4 1 2 满足最大堆定义,直接交换根节点元素
               2 6 3 5 4 1 7,交换完毕
               6 5 3 2 4 1 7,调整完毕
               1 5 3 2 4 6 7,交换完毕
               5 4 3 2 1 6 7,调整完毕
               1 4 3 2 5 6 7,交换完毕
               4 2 3 1 5 6 7,调整完毕
               1 2 3 4 5 6 7,交换完毕,此时虽然已有序,但仍需进行最大堆调整,因为最大堆算法时间复杂度为nlog2n,会进行继续搜索调整
               3 2 1 4 5 6 7,调整完毕,移动一次
               1 2 3 4 5 6 7,交换完毕,移动两次
               2 1 3 4 5 6 7,调整完毕
               1 2 3 4 5 6 7,交换完毕
        

发表于 2015-08-31 16:59:40 回复(10)
我一开始看错题,以为是一趟排序,所以选的0,如果是整个排序过程,3应该只移动了2次,就是最后3放入堆顶1次(下标从2变为0),然后跟当前堆的最后一个元素交换1次(下标从0变为2),一共2次。
发表于 2015-08-25 11:03:47 回复(7)
堆排序:
a.将无需序列构建成一个堆,根据升序降序需求选择大顶堆或小顶堆;

b.将堆顶元素与末尾元素交换,将最大元素"沉"到数组末端;

c.重新调整结构,使其满足堆定义,然后继续交换堆顶元素与当前末尾元素,反复执行调整+交换步骤,直到整个序列有序

发表于 2018-12-26 11:43:01 回复(0)
就是大根堆变为小根堆
发表于 2022-03-19 16:43:12 回复(0)
先将7-6-3-5-4-1-2调整为初始堆,每次将堆顶元素与最后一个元素互换位置,堆顶元素被换下来即可组成一个有序的结果。互换后继续调整为大顶堆。
发表于 2021-12-20 08:36:32 回复(0)
难道不应该是小根堆吗

发表于 2021-02-20 09:36:21 回复(0)
真没想到放在最后也算一次😂
发表于 2020-07-10 17:22:50 回复(0)
数字3的位置移动有3次,但是由于其中两次都是位置0,因此变动2次。 1.数字3为堆尾的时候,交换堆顶元素,位置由2变为0,下沉之后,位置又变为1 2.此时元素剩余2个,再交换,此时3的位置又变为了0,所以位置改变了3次,但是有一次是相同的,因此也可以理解为只变了2次。
发表于 2020-05-18 13:01:53 回复(0)
可以借助图像帮助理解堆排序的过程
发表于 2018-06-02 13:47:30 回复(0)
看了好长时间的堆排序,似懂非懂
每次交换完后对堆进行调整,重新调整为大根堆?然后再进行交换和调整
不知道理解的对不对
发表于 2017-08-15 15:21:18 回复(0)
堆排序是位置一定,找该位置元素的排序方式。3本来就在自己本身位置上。由于采用的是堆排序,有建堆和排序过程。初始建堆时,3放入堆顶1次(下标从2变为0),堆排序归位时,跟当前堆的最后一个元素交换1次(下标从0变为2),一共2次。
发表于 2017-06-23 17:09:33 回复(0)
考察堆排序的先后顺序,改变2次,画图分析即可。
发表于 2017-04-27 11:07:21 回复(0)
如果最后一步 “3”出堆也算一次的话就是2次
发表于 2017-04-06 11:27:52 回复(0)