数据结构之——堆排序

堆排序是一种排序算法,主要包含创建堆和调整堆的过程。创建堆时自下而上进行,若交换导致子树不满足最大堆,则需自上调整。在排序过程中仅交换数组元素,不改变堆的物理存储。堆排序通过不断调整找到最大值并移至数组末尾,直至排序完成。代码实现中,循环边界需细心调试。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

堆排序过程详解

堆排序主要是两个过程:1.创建堆,

          2.每次交换堆顶和最后一个元素的值,调整堆,堆顶元素即为最大值

需要注意的是:创建堆的过程中,是自下而上进行调整,而且在调整的过程中包含了自上而下的调整。因为在自下而上的调整中,若是交换了某个左孩子或者 右孩子与其父节点的值,可能会造成其相应的左子树或者右子树不满足最大堆的约束,所以,以此左孩子或者右孩子为根节点的左子树或者右子树,需要自上 进行调整。这个地方需要注意。


还需要注意的一点内容就是,我们在整个堆排序的过程中。只是在对数组A中的元素交换来交换区,并不涉及一个堆的实际物理存储。只不过是对A中的具体元 应该怎么交换的一种具体的图像形式的表示而已。


堆排序的实质是在每次堆调整中,找到数组中的最大值放到堆顶(数组第一个元素),然后交换到堆中最后一个节点(数组最后一个元素),然后堆的规模减 小一(即数组最后一个元素(已经是最大值)不参与到下一次的堆调整过程中),而每次寻找最大值的过程,就是堆进行调整的过程。



下面是具体的代码实现,循环过程中的边界都是一步步调试出来的,具体的代码功能,可参见注释。

package Sort;

import java.util.*;

public class HeapSort {
    public int[] heapSort(int[] A, int n) {
		//1.建堆
        A = createHeap(A,n);
        //2.将堆顶记录和堆中最后一个记录交换
        for(int i=n;i>1;i--){
            
            A[0] = A[0] + A[i-1];
            A[i-1] = A[0] - A[i-1];
            A[0] = A[0] - A[i-1];
             
            //3.筛选法调整堆,堆中记录减少一个
        	A = adjustHeap(A,0,i-1);  //从堆顶向下调整,所以传入0,每次调整数组个数减一
        }
        //4.重复第二步
        return A;
        }
   
    
    public int[] createHeap(int[] A,int n){
        for(int i=(n-2)/2;i>=0;i--){//自上而下进行堆调整,自上而下,非叶子节点的个数为(n-2)/2,因为数组索引从零开始,所以减2,只从最后一个非叶子节点调整就行。
            //对这棵子数进行调整,使其为最大堆
            A = adjustHeap(A,i,n);
        }
        return A;
    }
    
    public int[] adjustHeap(int[] A,int k,int n){  //n为节点的总个数,k为需要调整的非叶子节点,根据K可以求得其左孩子和右孩子
        if(2*k+1>=n) return A;
        int left = 2*k+1;
        int right = 2*k + 2;
        int max = left;//假设左孩子的值是最大的
        if(right<n&&A[right]>A[left]){
            max = right;  //如果右孩子的值比左孩子的值还要大,则令 max = right
        }
        if(A[k]<A[max]){   //如果根节点的值不是最大值,则与最大的孩子值进行交换
            A[k] = A[max] + A[k];
            A[max] = A[k] - A[max];
            A[k] = A[k] - A[max];
            A = adjustHeap(A,max,n); //其左孩子或者右孩子与根节点交换后,还得重新调整其子数,即,若是与左孩子交换,则调整左子树,如与右孩子交换,则调整右子树。
        }
        return A;
    }
    
    public static void main(String[] args) {
		int[] a = {3,5,8,9,1,2,3};
		HeapSort hs = new HeapSort();
		a = hs.heapSort(a, 7);
		System.out.println(Arrays.toString(a));
 	}
 }


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值