📜  门| GATE CS Mock 2018 |设置 2 |第 53 题(1)

📅  最后修改于: 2023-12-03 15:42:13.283000             🧑  作者: Mango

题目概述

本题为2022年门(GATE)计算机科学(CS)虚拟考试的一道题目,编号为第53题。本题的主要内容涉及到排序算法中的堆排序及递归实现。

题目描述

给定一个整数数组,需要使用堆排序算法将其从小到大进行排序。要求使用递归的方式实现堆排序算法。

输入格式

输入数据由两行组成:

  • 第一行包含一个整数n,表示数组的大小;
  • 第二行包括n个空格分隔的整数,表示待排序的数组内容。

输出格式

输出排序后的数组,每个数之间以空格隔开,不需要换行符。

样例输入

6
3 6 2 7 4 8

样例输出

2 3 4 6 7 8

题目解析

堆排序是一种基于选择排序的排序算法,通过构建大根堆或小根堆来实现排序。该算法的核心在于将无序数列转换成为一个堆结构,再将堆顶元素与堆底元素交换并重建堆,重复执行此操作,最终得到有序数列。

递归实现堆排序算法,主要分为以下几个步骤:

  • 构建大根堆或小根堆;
  • 交换堆顶元素与堆底元素,并重建堆结构;
  • 递归执行步骤2直至数组有序。

参考实现

下面是参考实现的代码:

public class HeapSort {
    public void sort(int arr[]) {
        int n = arr.length;

        // 构建大根堆
        for (int i = n / 2 - 1; i >= 0; i--)
            heapify(arr, n, i);

        // 交换堆顶元素与堆底元素,并重建堆
        for (int i=n-1; i>=0; i--) {
            int temp = arr[0];
            arr[0] = arr[i];
            arr[i] = temp;

            heapify(arr, i, 0);
        }
    }

    void heapify(int arr[], int n, int i) {
        int largest = i; 
        int l = 2*i + 1; 
        int r = 2*i + 2; 

        // 找到左右子节点中较大的一个
        if (l < n && arr[l] > arr[largest])
            largest = l;

        if (r < n && arr[r] > arr[largest])
            largest = r;

        // 如果有子节点比父节点大,则进行交换,并递归重建堆
        if (largest != i) {
            int swap = arr[i];
            arr[i] = arr[largest];
            arr[largest] = swap;

            heapify(arr, n, largest);
        }
    }
}

在以上实现中,sort()方法为递归实现的堆排序算法,heapify()方法用于构建大根堆或小根堆并重建堆结构。假设数组长度为n,则时间复杂度为O(n log n),空间复杂度为O(1)。