给定一个数组,数组内每一个元素的位置和其最终排序好的位置 的 距离相差在 k 以内,怎么有效的对其排序?要求时间复杂度为 O(n log k)
#include<iostream>
using namespace std;
void swap(int *x, int *y);
//小顶堆类
class MinHeap
{
int *harr; // 堆中的元素数组
int heap_size; // 堆的大小
public:
// 构造函数
MinHeap(int a[], int size);
// 从给定的下标开始调整堆
void MinHeapify(int);
//i的左孩子的下标
int left(int i) { return (2 * i + 1); }
// i的右孩子的下标
int right(int i) { return (2 * i + 2); }
//取走最小值(或者说是 root), 并添加新的元素x
int replaceMin(int x);
// 取最小值
int extractMin();
};
// k为每个元素的当前位置和排序数组位置相差的范围
int sortK(int arr[], int n, int k)
{
// 用前 (k+1) 个元素创建最小堆
int *harr = new int[k + 1];
for (int i = 0; i <= k && i<n; i++) // i < n 防止 k>n的情况
harr[i] = arr[i];
MinHeap hp(harr, k + 1);
for (int i = k + 1, ti = 0; ti < n; i++, ti++)
{
//如果有剩余元素,就替换掉堆顶
if (i < n)
arr[ti] = hp.replaceMin(arr[i]);
// 否则就依次取走堆顶的元素,
else
arr[ti] = hp.extractMin();
}
return 0;
}
// 以下是标准的小顶堆的实现
MinHeap::MinHeap(int a[], int size)
{
heap_size = size;
harr = a;
int i = (heap_size - 1) / 2;
while (i >= 0)
{
MinHeapify(i);//构建初始堆
i--;
}
}
//从小顶堆中移除堆顶元素
int MinHeap::extractMin()
{
int root = harr[0];
if (heap_size > 1)
{
harr[0] = harr[heap_size - 1];
heap_size--;
MinHeapify(0);
}
return root;
}
// 替换root和给定的x
int MinHeap::replaceMin(int x)
{
int root = harr[0];
harr[0] = x;
if (root < x)
MinHeapify(0);
return root;
}
// 调整小顶堆(递归的方法)
void MinHeap::MinHeapify(int i)
{
int l = left(i);
int r = right(i);
int smallest = i;
if (l < heap_size && harr[l] < harr[i])
smallest = l;
if (r < heap_size && harr[r] < harr[smallest])
smallest = r;
if (smallest != i)
{
swap(&harr[i], &harr[smallest]);
MinHeapify(smallest);
}
}
// 交换
void swap(int *x, int *y)
{
int temp = *x;
*x = *y;
*y = temp;
}
//打印数组
void printArray(int arr[], int size)
{
for (int i = 0; i < size; i++)
cout << arr[i] << " ";
cout << endl;
}
// 测试
int main()
{
int k = 3;
int arr[] = { 2, 6, 3, 12, 56, 8 };
int n = sizeof(arr) / sizeof(arr[0]);
sortK(arr, n, k);
cout << "Following is sorted array\n";
printArray(arr, n);
return 0;
}