堆排序(算法实现)

简介: 堆排序-算法实现前面介绍了堆的基本功能实现(https://blog.csdn.net/m0_46343224/article/details/127986662),了解了堆,这里用堆实现排序

堆排序-算法实现

前面介绍了堆的基本功能实现(https://blog.csdn.net/m0_46343224/article/details/127986662),了解了堆,这里用堆实现排序

1. 向上调整和向下调整比较

思考:向上调整和向下调整哪个更优?

44f91d7ce25e16bab8dec0b637c8fa9d.png此图解析:向上调整的时间复杂度:O(N*log2(N));向下调整的时间复杂度:O(N);则从尾向下调整优于向上调整

2. 堆排序

堆排序思路:

升序:首先建大堆,然后交换首尾数据(也就是把最大的数据放在尾部,再从头向下调整size-1个数据(也就是不对其交换后的最大的数据调整)

降序:首先建小堆,然后交换首尾数据(也就是把最大的数据放在尾部,再从头向下调整size-1个数据(也就是不对其交换后的最大的数据调整)

1. 升序

void SwapData(int* a, int* b)
{
  int tmp = *a;
  *a = *b;
  *b = tmp;
}
void AdjustDownSortAscending(int* a, int size, int parent)
{
  //假设默认左孩子大
  int lchild = parent * 2 + 1;
  while (lchild < size)
  {
    //确认指向大的孩子
    if (lchild + 1 < size && a[lchild + 1] > a[lchild])
    {
      ++lchild;
    }
    //大堆
    //lchild + 1 < size 表示最后的父节点和左孩子对比
    if (a[parent] < a[lchild])
    {
      SwapData(&a[parent], &a[lchild]);
      parent = lchild;
      lchild = parent * 2 + 1;
    }
    else
    {
      break;
    }
  }
}
void HeapSortAscending(int* a, int size)
{
  //建大堆(从尾元素父节点开始)
  for (int i = (size - 1 - 1) / 2; i >= 0; --i)
  {
    AdjustDownSortAscending(a, size, i);
  }
  int heapend = size - 1;
  while (heapend > 0)
  {
    SwapData(&a[0], &a[heapend]);
        //从首开始向下调整
    AdjustDownSortAscending(a, heapend, 0);
    heapend--;
  }
}

2. 降序

2. void SwapData(int* a, int* b)
{
  int tmp = *a;
  *a = *b;
  *b = tmp;
}
void AdjustDownSortDescending(int* a, int size, int parent)
{
  //假设默认左孩子大
  int lchild = parent * 2 + 1;
  while (lchild < size)
  {
    //确认指向大的孩子
    if (lchild + 1 < size && a[lchild + 1] < a[lchild])
    {
      ++lchild;
    }
    //大堆
    //lchild + 1 < size 表示最后的父节点和左孩子对比
    if (a[parent] > a[lchild])
    {
      SwapData(&a[parent], &a[lchild]);
      parent = lchild;
      lchild = parent * 2 + 1;
    }
    else
    {
      break;
    }
  }
}
void HeapSortDescending(int* a, int size)
{
  //建小堆(从尾元素父节点开始)
  for (int i = (size - 1 - 1) / 2; i >= 0; --i)
  {
    AdjustDownSortDescending(a, size,i);
  }
  int heapend = size - 1;
  while (heapend > 0)
  {
    SwapData(&a[0], &a[heapend]);
        //从首开始向下调整
    AdjustDownSortDescending(a, heapend, 0);
    heapend--;
  }
}

为什么升序建立大堆,降序建立小堆?

我们知道大堆小堆都不是连续递减或递增的,拿升序来说:如果建立小堆,那么我们不一定数据连续递增的情况时,这样就增加的时间复杂度,本来可以在O(N*log2(N))时间解决,但是这里不连续递增,就要对没有连续递增的位置上再次调整。降序建立大堆也是一样提高了不必的时间成本

6d041d21f180bbe290dbb765de3cf3d1.png










相关文章
|
7月前
|
算法 Python
数据结构算法--4堆排序
堆排序过程概述:建立大根堆,将堆顶最大元素移出并替换为末尾元素,调整保持堆性质,重复此过程直至堆为空,实现排序。时间复杂度为O(nlogn)。Python中可用heapq模块进行堆操作。
|
8月前
|
机器学习/深度学习 人工智能 算法
数据结构与算法:堆排序和TOP-K问题
朋友们大家好,本节内容来到堆的应用:堆排序和topk问题
数据结构与算法:堆排序和TOP-K问题
|
8月前
|
存储 人工智能 算法
深入浅出堆排序: 高效算法背后的原理与性能
深入浅出堆排序: 高效算法背后的原理与性能
129 1
|
3月前
|
算法 搜索推荐
数据结构与算法学习十八:堆排序
这篇文章介绍了堆排序是一种通过构建堆数据结构来实现的高效排序算法,具有平均和最坏时间复杂度为O(nlogn)的特点。
94 0
数据结构与算法学习十八:堆排序
|
3月前
|
算法 搜索推荐
算法之堆排序
本文介绍了堆排序算法的原理和实现,通过构建最大堆或最小堆,利用堆的性质进行高效的排序,并提供了具体的编程实现细节和示例。
38 0
算法之堆排序
|
3月前
|
算法 Java Go
深入了解堆排序算法
深入了解堆排序算法
52 1
|
8月前
|
移动开发 算法 前端开发
前端算法之堆排序
前端算法之堆排序
45 1
|
7月前
|
搜索推荐 算法 Java
Java中的快速排序、归并排序和堆排序是常见的排序算法。
【6月更文挑战第21天】Java中的快速排序、归并排序和堆排序是常见的排序算法。快速排序采用分治,以基准元素划分数组并递归排序;归并排序同样分治,先分割再合并有序子数组;堆排序通过构建堆来排序,保持堆性质并交换堆顶元素。每种算法各有优劣:快排平均高效,最坏O(n²);归并稳定O(n log n)但需额外空间;堆排序O(n log n)且原地排序,但不稳定。
55 3
|
7月前
|
搜索推荐 算法
【C/排序算法】:堆排序和选择排序
【C/排序算法】:堆排序和选择排序
44 0
|
7月前
|
存储 算法 C语言
数据结构和算法——堆排序(选择排序、思路图解、代码、时间复杂度、堆排序及代码)
数据结构和算法——堆排序(选择排序、思路图解、代码、时间复杂度、堆排序及代码)
43 0