算法-排序-k排序(算法导论第三版第八章思考题8-5)

28 篇文章 1 订阅
14 篇文章 0 订阅

算法-排序-k排序

算法导论第三版第八章思考题8-5
时间复杂度Θ(nlg(n/k))。
利用最小堆完成,把元素分成k个堆,每个堆大小⌈n/k⌉。
利用堆作为子排序稳定,也可以采用其他排序作为子排序,子排序的算法时间复杂度保证在Θ(klgk)就行。

#include "k_sort_heap.h"
int left_k_sort(int parent)
{
    return (parent << 1) + 1;
}
int right_k_sort(int parent)
{
    return (parent << 1) + 2;
}
void heapify_k_sort(int *array,int heap_size,int parent_index)
{
    int smallest = parent_index;
    int left = left_k_sort(parent_index);
    int right = right_k_sort(parent_index);
    if(left < heap_size && array[left]< array[smallest])
    {
        smallest = left;
    }
    if(right < heap_size && array[right] < array[smallest])
    {
        smallest = right;
    }
    if(smallest != parent_index)
    {
        int temp = array[parent_index];
        array[parent_index] = array[smallest];
        array[smallest] = temp;
        heapify_k_sort(array,heap_size,smallest);
    }
}
void build_k_sort_heap(int *array,int length)
{
    for (int i = length/2 - 1; i >=0; --i) {
        heapify_k_sort(array,length,i);
    }
}
int extra_minimum(int *array,int & heap_size)
{
    int minimum = array[0];
    array[0] = array[heap_size-1];
    heap_size--;
    heapify_k_sort(array,heap_size,0);
    return minimum;
}
void k_sort(int *array,int length,int k)
{
    int initial_heap_size = length/k + (length % k == 0 ? 0 : 1);
    int *heap = new int [initial_heap_size];
    int current_heap_size = 0;
    for (int i = 0; i < k; ++i) {
        for (int j = 0; j < initial_heap_size; ++j)
        {
          if(i + (j * k) < length)
          {
              heap[j] = array[i + (j * k)];
              current_heap_size++;
          }
        }
        build_k_sort_heap(heap,current_heap_size);
        int j = 0;
        while (current_heap_size>0)
        {
            array[i + (j * k)] = extra_minimum(heap,current_heap_size);
            j++;
        }
    }
    delete[] heap;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值