IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> 数据结构与算法 -> Java实现堆排序及详细图解 -> 正文阅读

[数据结构与算法]Java实现堆排序及详细图解

堆排序

前言

堆排序(HeapSort)是指利用堆这种数据结构所设计的一种排序算法。堆积是一个近似于完全二叉树的结构,同时满足子节点的键值总是小于(或者大于)其父节点。

每个节点的值都大于或者等于其左右子节点的值,称为大顶堆;或者每个节点的值都小于或者等于其左右子节点的值,称为小顶堆。

在这里插入图片描述

对堆中的节点按层进行编号,将这种逻辑结构映射到数组如下图所示:

在这里插入图片描述

该数组从逻辑上讲就是一个堆结构,并且有以下特点:

大顶堆:arr[i] >= arr[2i+1] && arr[i] >= arr[2i+2]

小顶堆:arr[i] <= arr[2i+1] && arr[i] <= arr[2i+2]

综上,堆排序的基本思想就是将待排序的序列构建成一个大顶堆,此时整个序列最大值就是堆顶的根节点。将其与末尾元素交换,此时末尾元素就成为最大值。然后将剩余n-1个元素重新构造成一个堆,这样会得到n个元素中的次小值,也就是n-1个元素中的最大值,并将其放置末尾,并如此反复,就能得到一个有序序列。


实现步骤

步骤一:构造初始堆,将给定无序序列构造成一个大顶堆

假定无序序列结构如下

在这里插入图片描述

此时从最后一个非叶子节点[6]开始,叶结点不用调整,从左至右,从上至下进行调整。

在这里插入图片描述

找到第二个非叶子节点[4],由于{4,8,9}中9元素最大,4和9交换。

在这里插入图片描述

此时,交换导致了子树{4,5,6}结构混乱,继续调整,现在6元素最大,交换4和6

在这里插入图片描述

步骤二:将堆顶元素与末尾元素进行交换,使末尾元素最大,然后继续调整堆,再将堆顶元素与末尾元素交换,如此反复重建和交换。

将堆顶元素9和末尾元素4进行交换

在这里插入图片描述

重新调整结构,使其继续满足堆定义

在这里插入图片描述

再将堆顶元素8与末尾元素5进行交换,得到第二大元素8

在这里插入图片描述

后续过程,继续进行调整,交换,如此反复调整,最终即可整个序列有序。


堆排序算法的基本思路总结:

  • 将无序序列建成一个堆,根据升降序需求选择大顶堆和小顶堆。
  • 将堆顶元素与末尾元素交换,将最大元素沉到数组末端。
  • 重新调整,使其重新满足堆定义,然后继续交换堆顶元素和当前末尾元素,反复执行调整和交换,直至整个序列有序。

代码实现

public static void heapSort(int[] array)
{
    //从倒数第一个非叶子节点开始
    for (int i = array.length/2 - 1; i>=0; i--)
    {
        //从第一天非叶子节点从下至上,从左至右调整结构
        adjustHeap(array,i, array.length);
    }

    //将堆顶元素与末尾元素交换 将最大元素沉到数组末尾 + 重新调整堆结构
    for (int i = array.length - 1; i > 0 ; i--)
    {
        //交换堆顶元素和末尾元素
        swap(array,0,i);
        //交换后的末尾元素忽略(j--) 不再参与堆结构的调整
        //重新调整堆结构
        adjustHeap(array,0,i);
    }

}

private static void swap(int[] array, int start, int end)
{
    int temp = array[start];
    array[start] = array[end];
    array[end] = temp;
}

public static void adjustHeap(int[] array,int index,int length)
{
    //取出当前元素
    int temp = array[index];
    //i节点是index节点的左子节点
    for (int i = 2 * index + 1; i < length; i = 2 * i + 1)
    {
        //表明左子节点小于右子节点
        if (i+1 < length && array[i] < array[i+1])
        {
            //将指针移至较大节点
            i++;
        }

        //如果子节点大于父节点
        if (array[i] > temp)
        {
            //将较大值赋给当前节点
            array[index] = array[i];
            //指针移向子节点
            index = i;
        }
        else
        {
            break;
        }
    }
    //循环结束,已经将最大值放在了堆顶
    //将temp值放到最终的位置
    array[index] = temp;
    
}

public static void main(String[] args)
{
    //升序
    int[] array = {4,6,8,78,13,19,1,5,9,};
    System.out.println("排序前=>"+ Arrays.toString(array));
    heapSort(array);
    System.out.println("排序后=>"+Arrays.toString(array));
}

输出结果

排序前=>[4, 6, 8, 78, 13, 19, 1, 5, 9]
排序后=>[1, 4, 5, 6, 8, 9, 13, 19, 78]

以上。

如有不足或错误欢迎评论指正。

  数据结构与算法 最新文章
【力扣106】 从中序与后续遍历序列构造二叉
leetcode 322 零钱兑换
哈希的应用:海量数据处理
动态规划|最短Hamilton路径
华为机试_HJ41 称砝码【中等】【menset】【
【C与数据结构】——寒假提高每日练习Day1
基础算法——堆排序
2023王道数据结构线性表--单链表课后习题部
LeetCode 之 反转链表的一部分
【题解】lintcode必刷50题<有效的括号序列
上一篇文章      下一篇文章      查看所有文章
加:2021-08-24 15:48:54  更:2021-08-24 15:48:56 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年11日历 -2024/11/25 22:50:08-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码