百度360必应搜狗淘宝本站头条
当前位置:网站首页 > 编程字典 > 正文

学习笔记-详解堆排序

toyiye 2024-06-21 12:02 14 浏览 0 评论

本文目的

上一章节已经详细的向大家介绍过排序的相关概念(学习笔记-排序简单介绍) ,本文旨在为大家详细的介绍堆排序。

堆排序

堆排序(英语:Heapsort)是指利用堆这种数据结构所设计的一种排序算法。堆是一个近似完全二叉树的结构,并同时满足堆积的性质:即子结点的键值或索引总是小于(或者大于)它的父节点。

堆是什么

堆(Heap)是计算机科学中一类特殊的数据结构的统称。堆是一种非线性结构。可以把堆看作一个数组,也可以被看作一个完全二叉树,通俗来讲堆其实就是利用完全二叉树的结构来维护的一维数组。此处用到的堆一般是指大顶堆或小顶堆。

大顶堆

每个结点的值都大于或等于其左右孩子结点的值,称为大顶堆。如下图所示。

小顶堆

每个结点的值都小于或等于其左右孩子结点的值,称为小顶堆。如下图所示。

算法原理

将待排序序列构造成一个大顶堆,此时,整个序列的最大值就是堆顶的根节点。将其与末尾元素进行交换,此时末尾就为最大值。然后将剩余n-1个元素重新构造成一个堆,这样会得到n个元素的次小值,如此反复执行,便能得到一个有序序列了。需要注意的是建立大顶堆时是从最后一个非叶子节点开始从下往上调整的。

算法流程

1. 创建一个堆 R[0……n-1];

2. 把堆首(最大值)和堆尾互换;

3. 把堆的尺寸缩小 1(已经有序的部分不进入下一轮);

4. 重复步骤 2,直到堆的尺寸为 1。

算法实现

操作过程如下:

1,初始化堆:将R[1..n]构造为堆;

2,将当前无序区的堆顶元素R[1]同该区间的最后一个记录交换,然后将新的无序区调整为新的堆。

#include <stdio.h> 
#define elemType int /*元素类型*/

int k=1;//轮次记录 

//打印函数 
void Print (elemType arr[], int len){
	
	int i;
	
	for (i=0; i<len; i++){
		printf ("%d\t", arr[i]);
	}
        
    printf("\n");
}

//记录交换 
void swap(int* a, int* b)
{
    int temp = *b;
    *b = *a;
    *a = temp;
}
 
//构建大顶堆 
void max_heapify(int a[], int start, int end) 
{
    //建立父节点指标和子节点指标
    int dad = start;
    int son = dad * 2 + 1;
    //若子节点指标在范围内才做比较
    while (son <= end){
        if (son + 1 <= end && a[son] < a[son + 1]) {
        	//先比较两个子节点大小,选择最大的
        	son++;
		} 
       
        //如果父节点大於子节点代表调整完毕,直接跳出函数
        if (a[dad] > a[son]){
        	return;
		}else{
		//否则交换父子内容再继续子节点和孙节点比较
            swap(&a[dad], &a[son]);
	        dad = son;
	        son = dad * 2 + 1;
       }
    }
}
 
//排序   
void Sort(elemType a[], int len)
{
    int i;
    //初始化,i从最後一个父节点开始调整
    for (i = len / 2 - 1; i >= 0; i--){
    	max_heapify(a, i, len - 1);
    } 
    
    for (i = len - 1; i > 0; i--) 
    {
    	//先将第一个元素和已排好元素前一位做交换,再重新调整,直到排序完毕
        swap(&a[0], &a[i]);
        max_heapify(a, 0, i - 1);
        
        printf("第===%d===轮排序后结果如下:\n",k);
		Print (a, 9);
		k=k+1;
    }
}

int main() {
	
	int i;
    elemType arr[9] = {94,19,29,9,11,1,14,13,29};
    printf("待排序的序列为:\n");
    Print(arr, 9);  
    printf("\n\n");
    
    Sort (arr,9);
    printf("\n\n");
    printf("排好序的结果如下:\n");
    Print(arr, 9);  
     
}

算法分析

时间复杂度

堆排序的运行时间主要是消耗在构建堆和在重建堆时的反复筛选上。在构建堆的过程,因为我们是从完全二叉树最下层的非叶子结点开始构建的,将它与其孩子结点进行比较和有必要的互换,对于每个非叶子结点来说,其实最多2次比较和互换,故初始化堆的时间复杂度为O(n)。在正式排序的时候,第i次取堆顶记录和重建堆需要O(logi)的时间(完全二叉树的某个结点到根结点的距离为log2i+1),并且需要取n-1次堆顶记录,因此重建堆的时间复杂度为O(nlogn)。所以总的来说,堆排序的时间复杂度为O(nlogn)。由于堆排序对元素记录的排序状态不敏感,因此它无论最好,最坏,和平均时间复杂度均为O(nlogn)。

空间复杂度

堆排序中只有交换元素时需要1个辅助空间,与问题规模无关,空间复杂度为O(1)。

排序稳定性

在构建堆的过程中无法保证相同值构建前后的相对位置,所以堆排序是不稳定的。


本文的初衷为学习笔记的分享,部分图文来源于网络,如侵,联删。

相关推荐

为何越来越多的编程语言使用JSON(为什么编程)

JSON是JavascriptObjectNotation的缩写,意思是Javascript对象表示法,是一种易于人类阅读和对编程友好的文本数据传递方法,是JavaScript语言规范定义的一个子...

何时在数据库中使用 JSON(数据库用json格式存储)

在本文中,您将了解何时应考虑将JSON数据类型添加到表中以及何时应避免使用它们。每天?分享?最新?软件?开发?,Devops,敏捷?,测试?以及?项目?管理?最新?,最热门?的?文章?,每天?花?...

MySQL 从零开始:05 数据类型(mysql数据类型有哪些,并举例)

前面的讲解中已经接触到了表的创建,表的创建是对字段的声明,比如:上述语句声明了字段的名称、类型、所占空间、默认值和是否可以为空等信息。其中的int、varchar、char和decimal都...

JSON对象花样进阶(json格式对象)

一、引言在现代Web开发中,JSON(JavaScriptObjectNotation)已经成为数据交换的标准格式。无论是从前端向后端发送数据,还是从后端接收数据,JSON都是不可或缺的一部分。...

深入理解 JSON 和 Form-data(json和formdata提交区别)

在讨论现代网络开发与API设计的语境下,理解客户端和服务器间如何有效且可靠地交换数据变得尤为关键。这里,特别值得关注的是两种主流数据格式:...

JSON 语法(json 语法 priority)

JSON语法是JavaScript语法的子集。JSON语法规则JSON语法是JavaScript对象表示法语法的子集。数据在名称/值对中数据由逗号分隔花括号保存对象方括号保存数组JS...

JSON语法详解(json的语法规则)

JSON语法规则JSON语法是JavaScript对象表示法语法的子集。数据在名称/值对中数据由逗号分隔大括号保存对象中括号保存数组注意:json的key是字符串,且必须是双引号,不能是单引号...

MySQL JSON数据类型操作(mysql的json)

概述mysql自5.7.8版本开始,就支持了json结构的数据存储和查询,这表明了mysql也在不断的学习和增加nosql数据库的有点。但mysql毕竟是关系型数据库,在处理json这种非结构化的数据...

JSON的数据模式(json数据格式示例)

像XML模式一样,JSON数据格式也有Schema,这是一个基于JSON格式的规范。JSON模式也以JSON格式编写。它用于验证JSON数据。JSON模式示例以下代码显示了基本的JSON模式。{"...

前端学习——JSON格式详解(后端json格式)

JSON(JavaScriptObjectNotation)是一种轻量级的数据交换格式。易于人阅读和编写。同时也易于机器解析和生成。它基于JavaScriptProgrammingLa...

什么是 JSON:详解 JSON 及其优势(什么叫json)

现在程序员还有谁不知道JSON吗?无论对于前端还是后端,JSON都是一种常见的数据格式。那么JSON到底是什么呢?JSON的定义...

PostgreSQL JSON 类型:处理结构化数据

PostgreSQL提供JSON类型,以存储结构化数据。JSON是一种开放的数据格式,可用于存储各种类型的值。什么是JSON类型?JSON类型表示JSON(JavaScriptO...

JavaScript:JSON、三种包装类(javascript 包)

JOSN:我们希望可以将一个对象在不同的语言中进行传递,以达到通信的目的,最佳方式就是将一个对象转换为字符串的形式JSON(JavaScriptObjectNotation)-JS的对象表示法...

Python数据分析 只要1分钟 教你玩转JSON 全程干货

Json简介:Json,全名JavaScriptObjectNotation,JSON(JavaScriptObjectNotation(记号、标记))是一种轻量级的数据交换格式。它基于J...

比较一下JSON与XML两种数据格式?(json和xml哪个好)

JSON(JavaScriptObjectNotation)和XML(eXtensibleMarkupLanguage)是在日常开发中比较常用的两种数据格式,它们主要的作用就是用来进行数据的传...

取消回复欢迎 发表评论:

请填写验证码