堆排序

堆排序

通过阅读《算法导论》第六章,学习了堆排序。

本文主要列出堆排序算法执行步骤和C++、Python代码。

算法名次堆排序
类别排序算法
复杂度nlgn
实现形式链表,数组(原地址排序)
参考书算法导论

C++代码

#include <iostream>

/////////////////////
//思路:
//1、建立函数max_heapify:用于对指定节点执行堆排序
//2、建立函数build_max_heap:调用函数max_heapify,便利所有非叶子节点,建立一个最大堆
//3、建立函数heap_sort:调用函数build_max_heap建立一个最大堆后,将跟节点与与最后一个节点交换,再调用函数max_heapify(除最后一个节点外)对根节点执行对排序,然后重复上述操作,直到所有节点执行完毕节点
/////////////////////

/////////////////////
//函数名:max_heapify
//函数功能:对指定节点执行堆排序
//输入变量:
// heap_array:堆数组(下标从1开始),节点i的左右子节点分别为2*i和2*i+1
// index:整型,待排序节点的下标
// heap_length:整型,待排序堆的节点个数
//输出变量:无
/////////////////////
void max_heapify(int heap_array[], int index, int heap_length)
{
  int left_index = index * 2;       //存放左子节点下标
  int right_index = index * 2 + 1;  //存放右子节点下标

  int larger_index = index;         //存放较大子节点下标

  //如果左子节点大于根节点,则larger_index标签转换
  if((left_index <= heap_length) && (heap_array[left_index] > heap_array[index]))
    larger_index = left_index;

  //如果右子节点大于较大节点,则larger_index标签转换
  if((right_index <= heap_length) && (heap_array[right_index] > heap_array[larger_index]))
    larger_index = right_index;

  //如果根节点不是最大的,则进行交换,并继续对对应的子节点执行排序操作(递归调用)
  if(larger_index != index)
  {
    int tmp_value = heap_array[index];
    heap_array[index] = heap_array[larger_index];
    heap_array[larger_index] = tmp_value;

    max_heapify(heap_array, larger_index, heap_length);
  }
}

/////////////////////
//函数名:build_max_heap
//函数功能:调用函数max_heapify,便利所有非叶子节点,建立一个最大堆
//输入变量:
// heap_array:堆数组(下标从1开始),节点i的左右子节点分别为2*i和2*i+1
// heap_length:整型,待排序堆的节点个数,最后一个非叶子节点为heap_length/2
//输出变量:无
/////////////////////
void build_max_heap(int heap_array[], int heap_length)
{
  int last_leaf_index = heap_length / 2;

  //从最后一个非叶子节点到根节点,依次进行堆排序
  for(int index = last_leaf_index; index >= 1; --index)
    max_heapify(heap_array, index, heap_length);
}

/////////////////////
//函数名:heap_sort
//函数功能:调用函数build_max_heap建立一个最大堆后,将跟节点与与最后一个节点交换,再调用函数max_heapify(除最后一个节点外)对根节点执行对排序,然后重复上述操作,直到所有节点执行完毕节点
//输入变量:
// heap_array:堆数组(下标从1开始),节点i的左右子节点分别为2*i和2*i+1
// heap_length:整型,待排序堆的节点个数,最后一个非叶子节点为heap_length/2
//输出变量:无
/////////////////////
void heap_sort(int heap_array[], int heap_length)
{
  //获得第一个最大堆
  build_max_heap(heap_array, heap_length);

  for(int index = heap_length; index >= 2; --index)
  {
    //将最大节点(根节点)调整到最后一个节点
    int tmp_value = heap_array[index];
    heap_array[index] = heap_array[1];
    heap_array[1] = tmp_value;

    //对根节点(基于剩余节点的堆)执行堆排序
    max_heapify(heap_array, 1, index - 1);
  }
}


int main()
{
  int array[] = {-9999, 1, 234, 45, 67, 21, 975, 5275, 867, -12, -200};

  int num = 10;

  printf("待排序数组顺序为:");
  for(int i = 1; i <= num; ++i)
    printf("%d ", array[i]);

  printf("\n");

  heap_sort(array, num);

  printf("已排序序数组顺序为:");
  for(int i = 1; i <= num; ++i)
    printf("%d ", array[i]);

  printf("\nFinished.\n");

  return 0;
}

执行结果
待排序数组顺序为:1 234 45 67 21 975 5275 867 -12 -200
已排序序数组顺序为:-200 -12 1 21 45 67 234 867 975 5275
Finished.
Press any key to continue…

Python代码

####################
#思路:
#1、建立函数max_heapify:用于对指定节点执行堆排序
#2、建立函数build_max_heap:调用函数max_heapify,便利所有非叶子节点,建立一个最大堆
#3、建立函数heap_sort:调用函数build_max_heap建立一个最大堆后,将跟节点与与最后一个节点交换,再调用函数max_heapify(除最后一个节点外)对根节点执行对排序,然后重复上述操作,直到所有节点执行完毕节点
####################

####################
#函数名:max_heapify
#函数功能:对指定节点执行堆排序
#输入变量:
# heap_array:堆数组(下标从1开始),节点i的左右子节点分别为2*i和2*i+1
# index:整型,待排序节点的下标
# heap_length:整型,待排序堆的节点个数
#输出变量:无
####################
def max_heapify(heap_array, index, heap_length):
    left_index = index * 2       #存放左子节点下标
    right_index = index * 2 + 1  #存放右子节点下标

    larger_index = index        #存放较大子节点下标

    #如果左子节点大于根节点,则larger_index标签转换
    if left_index <= heap_length and heap_array[left_index] > heap_array[index]:
        larger_index = left_index

    #如果右子节点大于较大节点,则larger_index标签转换
    if right_index <= heap_length and heap_array[right_index] > heap_array[larger_index]:
            larger_index = right_index

    #如果根节点不是最大的,则进行交换,并继续对对应的子节点执行排序操作(递归调用)
    if larger_index != index:
        tmp_value = heap_array[index]
        heap_array[index] = heap_array[larger_index]
        heap_array[larger_index] = tmp_value
        max_heapify(heap_array, larger_index, heap_length)

####################
#函数名:build_max_heap
#函数功能:调用函数max_heapify,便利所有非叶子节点,建立一个最大堆
#输入变量:
# heap_array:堆数组(下标从1开始),节点i的左右子节点分别为2*i和2*i+1
# heap_length:整型,待排序堆的节点个数,最后一个非叶子节点为heap_length/2
#输出变量:无
####################
def build_max_heap(heap_array, heap_length):
    last_leaf_index = int(heap_length / 2)

    #从最后一个非叶子节点到根节点,依次进行堆排序
    for index in range(last_leaf_index, 0, -1):
        max_heapify(heap_array, index, heap_length)

####################
#函数名:heap_sort
#函数功能:调用函数build_max_heap建立一个最大堆后,将跟节点与与最后一个节点交换,再调用函数max_heapify(除最后一个节点外)对根节点执行对排序,然后重复上述操作,直到所有节点执行完毕节点
#输入变量:
# heap_array:堆数组(下标从1开始),节点i的左右子节点分别为2*i和2*i+1
# heap_length:整型,待排序堆的节点个数,最后一个非叶子节点为heap_length/2
#输出变量:无
####################
def heap_sort(heap_array, heap_length):
    #获得第一个最大堆
    build_max_heap(heap_array, heap_length)

    for index in range(heap_length, 1, -1):
        #将最大节点(根节点)调整到最后一个节点
        tmp_value = heap_array[index]
        heap_array[index] = heap_array[1]
        heap_array[1] = tmp_value

        #对根节点(基于剩余节点的堆)执行堆排序
        max_heapify(heap_array, 1, index - 1)



if __name__ == '__main__':
    array = [-9999, 1, 234, 45, 67, 21, 975, 5275, 867, -12, -200]

    print("待排序数组为:", array[1 : ])

    heap_sort(array, 10)

    print("已排序数组为:", array[1 : ])

执行结果
python3 heap_sort.py
待排序数组为: [1, 234, 45, 67, 21, 975, 5275, 867, -12, -200]
已排序数组为: [-200, -12, 1, 21, 45, 67, 234, 867, 975, 5275]

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值