C语言 数据结构堆排序顺序存储(升序)

C语言 数据结构堆排序顺序存储(升序)攻略

1. 堆排序概述

堆排序是一种常见的排序算法,通过构建最大堆或最小堆来实现排序。本文介绍的是使用顺序存储方式实现的最大堆排序,也就是升序排序。

2. 最大堆的定义和实现

最大堆指的是堆结构中父节点的值大于子节点的值,根节点的值最大。对于一棵完全二叉树,若父节点的下标为i,则其左子节点的下标为2i+1,右子节点的下标为2i+2。下面是最大堆的实现代码:

void adjustHeap(int a[], int i, int n)
{
    int j, temp = a[i];
    for (j = 2 * i + 1; j < n; j = 2 * j + 1)
    {
        if (j < n - 1 && a[j] < a[j+1])
            ++j;

        if (temp >= a[j])
            break;

        a[i] = a[j];
        i = j;
    }
    a[i] = temp;
}

void buildHeap(int a[], int n)
{
    int i;
    for (i = n / 2 - 1; i >= 0; --i)
        adjustHeap(a, i, n);
}

其中,adjustHeap是调整堆的函数,用于将以i为父节点的子树调整为最大堆,n为数组大小;buildHeap是建堆函数,用于将整个数组调整为最大堆。

3. 堆排序的实现

堆排序的过程就是不断将堆顶元素(最大值)与堆底元素交换,再调整剩余元素为最大堆,以此类推,直到整个数组有序。堆排序的实现代码如下:

void heapSort(int a[], int n)
{
    int i, temp;
    buildHeap(a, n);
    for (i = n - 1; i > 0; --i)
    {
        temp = a[0];
        a[0] = a[i];
        a[i] = temp;
        adjustHeap(a, 0, i);
    }
}

其中,buildHeap调整整个数组为最大堆,heapSort函数则用于完成整个堆排序的过程。

4. 示例说明

示例一

假设一个数组为{7, 3, 1, 5, 2, 4, 6},经过堆排序过程后,数组应该为{1, 2, 3, 4, 5, 6, 7},下面是详细的堆排序过程:

  1. 首先调整整个数组为最大堆,得到{7, 5, 4, 3, 2, 1, 6}
  2. 将堆顶元素7与堆底元素6交换,得到{6, 5, 4, 3, 2, 1, 7},此时下标为0~5的元素为最大堆
  3. 将堆顶元素6与堆底元素1交换,得到{1, 5, 4, 3, 2, 6, 7},此时下标为0~4的元素为最大堆
  4. 将堆顶元素1与堆底元素2交换,得到{2, 5, 4, 3, 1, 6, 7},此时下标为0~3的元素为最大堆
  5. 将堆顶元素2与堆底元素3交换,得到{3, 5, 4, 2, 1, 6, 7},此时下标为0~2的元素为最大堆
  6. 将堆顶元素3与堆底元素1交换,得到{1, 5, 4, 2, 3, 6, 7},此时下标为0~1的元素为最大堆
  7. 将堆顶元素1与堆底元素0交换,得到{1, 5, 4, 2, 3, 6, 7},此时整个数组有序

示例二

假设一个数组为{1, 2, 3, 4, 5, 6, 7},经过堆排序过程后,数组应该还是{1, 2, 3, 4, 5, 6, 7},因为数组已经有序,所以只需调用buildHeap函数构建最大堆即可。

5. 总结

堆排序是一种常见的排序算法,其时间复杂度为O(nlogn)。本文介绍了使用顺序存储方式实现的最大堆排序,包括最大堆的定义和实现,以及堆排序的具体实现过程和示例说明。

本站文章如无特殊说明,均为本站原创,如若转载,请注明出处:C语言 数据结构堆排序顺序存储(升序) - Python技术站

(0)
上一篇 2023年5月17日
下一篇 2023年5月17日

相关文章

  • Java 中很好用的数据结构(你绝对没用过)

    Java 中很好用的数据结构(你绝对没用过) 介绍 Java 中的数据结构有很多,比如数组、链表、栈、队列、堆、树等等。在这些常见的数据结构中,我们或多或少都会使用到。但是本篇文章要讲述的是一些比较冷门,但是很好用的数据结构。 双向队列(Deque) 双向队列,顾名思义,是一种可以双向操作的队列。它可以从队列的两端插入和删除元素,因此常被用作实现栈和队列以及…

    数据结构 2023年5月17日
    00
  • TypeScript数据结构链表结构 LinkedList教程及面试

    TypeScript数据结构链表结构 LinkedList教程及面试攻略 在程序设计中,链表是一种重要的数据结构,它可以用来存储一系列数据元素,并提供一些类似于数组的操作。 TypeScript是一种JavaScript的超集,它提供了更加丰富的类型系统,使得我们可以更好的使用链表这种数据结构。 本文将会讲解使用TypeScript实现常见的链表结构,并且提…

    数据结构 2023年5月17日
    00
  • C语言数据结构算法基础之循环队列示例

    标题:C语言数据结构算法基础之循环队列示例 1. 简介 循环队列是一种常见的数据结构,它采用固定大小的数组来模拟队列的数据结构,可以高效地处理队列的进出操作。本文将会讲解循环队列的实现原理和示例代码。 2. 循环队列基本原理 循环队列通过两个指针front和rear来实现队列的添加和删除操作。在初始化时,front和rear的初始值都为0。每当数据进入队列时…

    数据结构 2023年5月17日
    00
  • C语言编程简单却重要的数据结构顺序表全面讲解

    C语言编程简单却重要的数据结构顺序表全面讲解 什么是顺序表? 顺序表是一种线性表,指的是一组有限元素的有限序列,其元素的逻辑顺序与它们在分配到的内存地址上的物理顺序相同或者等价。也就是说,顺序表中的元素按照其在内存中的位置依次存放。 顺序表的实现方式 顺序表的实现方式一般是使用数组,数组中的每一个元素对应着顺序表中的一个元素,位置相对应。 顺序表的优点 支持…

    数据结构 2023年5月17日
    00
  • 线段树好题! P2824 [HEOI2016/TJOI2016]排序 题解

    题目传送门 前言 线段树好题!!!!咕咕了挺久的一道题目,很早之前就想写了,今天终于找了个时间A掉了。 题意 给定一个 \(1\) 到 \(n\) 的排列,有 \(m\) 次操作,分两种类型。1.0 l r表示将下标在 \([l, r]\) 区间中的数升序排序。2.1 l r表示将下标在 \([l, r]\) 区间中的数降序排序。给定一个数 \(q\) 询问…

    算法与数据结构 2023年4月17日
    00
  • C++ 数据结构二叉树(前序/中序/后序递归、非递归遍历)

    下面是关于C++二叉树数据结构的详细攻略。 什么是二叉树 二叉树是一种树形数据结构,每个节点最多有两个子节点:左节点和右节点。一个节点没有左节点或右节点则分别为左子树和右子树为空。 递归遍历二叉树 前序遍历 前序遍历是指对于一棵二叉树,在访问右子树之前,先访问根节点,然后访问左子树。 下面是C++递归遍历二叉树的前序遍历示例代码: template <…

    数据结构 2023年5月17日
    00
  • Java数据结构之队列(动力节点Java学院整理)

    Java数据结构之队列(动力节点Java学院整理) 队列是一种有序列表,在其中所有插入操作必须在后端进行,而所有的删除操作必须在前端进行的数据结构。这种结构有时被称为先进先出(FIFO)。 队列的分类 普通队列:队列和栈一样,都是只能在一端进行插入操作,在另一端进行删除操作的特殊线性表。队列的特点是:先进先出。适用于数据必须按照插入顺序处理的必要场合。 双端…

    数据结构 2023年5月17日
    00
  • C语言超详细讲解双向带头循环链表

    C语言双向带头循环链表 基本概念 带头双向循环链表是指在双向循环链表的基础上,在头节点前面添加一个头结点。这个头结点不存储任何数据,只是为了方便对链表进行操作。循环链表则是在单向或双向链表的基础上,使链表的头节点与尾节点相连,形成一个环。 综合这两种链表,就构成了“双向带头循环链表”这种数据结构。双向带头循环链表是一种灵活性较高的数据结构,支持前插、后插、前…

    数据结构 2023年5月17日
    00
合作推广
合作推广
分享本页
返回顶部