八大排序算法~堆排序

简介: 八大排序算法~堆排序

八大排序算法~堆排序


1,思想:就是利用堆数据结构特点进行排序【堆结构特点~完全二叉树,而咱排序主要是利用(大根堆或者小根堆特点进行排序)】

【小根堆】每一个父结点的值都比子结点小,因为每个父节点都比子结点小,咱知道 小根堆的最小值就在根结点

【大根堆】每一个父结点的值都比子结点大因为每个父节点都比子结点大,咱知道  根堆的最大值就在根结点

(补充一下,因为小根堆要求只是父结点大于子结点,没有要求左右结点的大小关系噢,大根堆也是哈,咱对左右结点大小关系没有关系哈)

 

2,接下来,咱以大根堆排序为例,讲述好堆排序过程:

我觉得它的思想有些类似于咱总结的“冒泡思想”~

冒泡思想~(从小到大排序哈)【后座就认为是后边哈,没有啥特别,叫后座主要是为了强调后边啦】


冒泡排序思想:从第一个数开始找,要把大数“排除在外”~为大数找后座。(从小到大排序哈)
  外层循环~需要放后的大数个数;
    内循环~从第一个数拿起与后面位置的数两两比较,实力强的占的位置靠后。


堆排序思想~(从小到大排序哈)~刚好借助大根堆的特点进行排序


堆排序(借助大根堆,实现从小到大排序)思想:
咱对n个结点构建成一个大根堆,然后取根结点(最大值“排除在外”~放到后座上最后一个位置),
咱在对剩余的n-1个结点构建成一个新的大根堆,然后又取根结点放到后座上倒数第二个位置,
然后对剩余的n-2个结点构建成一个新的大根堆,然后又取根结点放到后座上倒数第三个位置,
........
直到剩下一个结点结束。//过程:(1)建立成大根堆,(2)for循环(从 i=最后一个结点位置开始直到i=第一个结点 结束):取根结点放于后座~即进行交换,根结点与后座最后一个位置进行交换,然后重构成新的大根堆,再取根节点跟后座倒数第二个位置交换,然后重新构建新的大根堆,然后。。。ps:本菜菜小白想请问,为什么要先初始化堆,然后for循环 取根结点,重新调整成堆;为什么不能for循环 调整成堆,然后取根结点,然再次调整成堆,然后再取根结点,再调整成堆。。。。就是为什么要单独初始化堆,不把它写到循环里?


3,代码:引自~《【算法】排序算法之堆排序》~https://zhuanlan.zhihu.com/p/124885051

             【这个 “developer1024 ” 作者大大这篇文章里的动画可以让你秒懂堆排的】


#include <stdio.h>
#include <stdlib.h>
void swap(int* a, int* b) {
    int temp = *b;
    *b = *a;
    *a = temp;
}
void max_heapify(int arr[], int start, int end) {
    //建立父节点指标和子节点指标
    int dad = start;
    int son = dad * 2 + 1;
    while (son <= end) { //若子节点指标在范围内才做比较
        if (son + 1 <= end && arr[son] < arr[son + 1]) //先比较两个子节点大小,选择最大的
            son++;
        if (arr[dad] > arr[son]) //如果父节点大于子节点代表调整完毕,直接跳出函数
            return;
        else { //否则交换父子内容再继续子节点和孙节点比较
            swap(&arr[dad], &arr[son]);
            dad = son;
            son = dad * 2 + 1;
        }
    }
}
void heap_sort(int arr[], int len) {
    int i;
    //初始化,i从最后一个父节点开始调整
    for (i = len / 2 - 1; i >= 0; i--)
        max_heapify(arr, i, len - 1);
    //先将第一个元素和已排好元素前一位做交换,再从新调整,直到排序完毕
    for (i = len - 1; i > 0; i--) {
        swap(&arr[0], &arr[i]);
        max_heapify(arr, 0, i - 1);
    }
}
int main() {
    int arr[] = { 3, 5, 3, 0, 8, 6, 1, 5, 8, 6, 2, 4, 9, 4, 7, 0, 1, 8, 9, 7, 3, 1, 2, 5, 9, 7, 4, 0, 2, 6 };
    int len = (int) sizeof(arr) / sizeof(*arr);
    heap_sort(arr, len);
    int i;
    for (i = 0; i < len; i++)
        printf("%d ", arr[i]);
    printf("\n");
    return 0;
}



目录
相关文章
|
算法 Python
数据结构算法--4堆排序
堆排序过程概述:建立大根堆,将堆顶最大元素移出并替换为末尾元素,调整保持堆性质,重复此过程直至堆为空,实现排序。时间复杂度为O(nlogn)。Python中可用heapq模块进行堆操作。
|
机器学习/深度学习 人工智能 算法
数据结构与算法:堆排序和TOP-K问题
朋友们大家好,本节内容来到堆的应用:堆排序和topk问题
数据结构与算法:堆排序和TOP-K问题
|
2月前
|
存储 算法 搜索推荐
软考算法破壁战:从二分查找到堆排序,九大排序核心速通指南
专攻软考高频算法,深度解析二分查找、堆排序、快速排序核心技巧,对比九大排序算法,配套动画与真题,7天掌握45%分值模块。
134 1
软考算法破壁战:从二分查找到堆排序,九大排序核心速通指南
|
9月前
|
存储 搜索推荐 算法
算法系列之排序算法-堆排序
堆排序(Heap Sort)是一种基于堆数据结构的比较排序算法。它的时间复杂度为 $O(nlogn)$,并且是一种原地排序算法(即不需要额外的存储空间)。堆排序的核心思想是利用堆的性质来维护一个最大堆或最小堆,然后逐步将堆顶元素(最大值或最小值)取出,放到数组的末尾,最终得到一个有序的数组。
234 8
算法系列之排序算法-堆排序
|
移动开发 算法 前端开发
前端算法之堆排序
前端算法之堆排序
99 1
|
算法 搜索推荐
算法之堆排序
本文介绍了堆排序算法的原理和实现,通过构建最大堆或最小堆,利用堆的性质进行高效的排序,并提供了具体的编程实现细节和示例。
108 1
算法之堆排序
|
算法 搜索推荐
数据结构与算法学习十八:堆排序
这篇文章介绍了堆排序是一种通过构建堆数据结构来实现的高效排序算法,具有平均和最坏时间复杂度为O(nlogn)的特点。
353 0
数据结构与算法学习十八:堆排序
|
算法 Java Go
深入了解堆排序算法
深入了解堆排序算法
241 1
|
搜索推荐 算法 Java
Java中的快速排序、归并排序和堆排序是常见的排序算法。
【6月更文挑战第21天】Java中的快速排序、归并排序和堆排序是常见的排序算法。快速排序采用分治,以基准元素划分数组并递归排序;归并排序同样分治,先分割再合并有序子数组;堆排序通过构建堆来排序,保持堆性质并交换堆顶元素。每种算法各有优劣:快排平均高效,最坏O(n²);归并稳定O(n log n)但需额外空间;堆排序O(n log n)且原地排序,但不稳定。
150 3
|
人工智能 搜索推荐 算法
sort-04-heap sort 堆排序算法详解
这是一个关于排序算法的系列文章摘要,包括了10篇关于不同排序算法的链接,如冒泡排序、快速排序、选择排序、堆排序等。堆排序是一种基于比较的排序算法,利用了近似完全二叉树的结构并满足最大堆或最小堆的性质。最大堆中,每个节点的值都大于或等于其子节点。文章详细解释了最大堆的概念、节点访问方式以及堆的操作,包括堆调整和堆排序的过程,并通过图解展示了堆排序的具体步骤。此外,还提供了一个Java实现的堆排序代码示例。整个排序系列来源于一个开源项目,读者可以通过链接查看完整内容。
sort-04-heap sort 堆排序算法详解

热门文章

最新文章