C语言数据结构之堆排序的优化算法

C语言数据结构之堆排序的优化算法攻略

堆排序简介

堆排序(HeapSort)是一种树形选择排序,在排序过程中始终保持一个最大堆,每次将堆顶元素与最后一个元素交换位置,并进行一次最大堆调整操作,直到整个序列有序为止。

堆排序的时间复杂度为O(nlogn),具有不需额外存储空间的特点,因此广泛应用于内存受限的场景。

堆排序的优化算法

1. 建堆操作的优化

将序列中的元素插入到空堆中,时间复杂度为O(nlogn),可以通过优化建堆操作,将其时间复杂度降至O(n)。

建堆操作的本质是将序列中的元素依次插入到堆中,因此可以考虑一次性将序列中的所有元素插入到堆中。具体方法如下:

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

由于完全二叉树中叶子节点占据了一半的空间,因此从第n/2个节点开始(包括第n/2个节点)是堆中所有非叶子节点。从第n/2个节点开始,从后往前依次执行heapify操作,即每次将当前节点和其子节点进行比较并进行调整。由于叶子节点不需要调整,因此可以忽略叶子节点,将操作次数降至一半。

2. 堆调整操作的优化

堆调整操作的本质是将某个节点的值减小,从而可能影响到该节点的子节点,需要依次将该节点与其子节点进行比较,对不满足堆性质的节点进行调整。由于每次调整只是将节点移动到正确的位置,因此可以考虑将堆调整操作优化为插入操作。

具体方法如下:

void heapInsert(int a[], int n, int k) {
    int cur = n;
    a[cur] = k;
    while (cur > 1 && k > a[cur / 2]) {
        a[cur] = a[cur / 2];
        cur /= 2;
    }
    a[cur] = k;
}

每次将堆的最后一个元素插入到堆中,由于插入元素的大小可能会影响到堆的调整,因此需要按照子节点的大小依次将该元素与其父节点进行比较。如果插入元素比父节点大,则将父节点移动到当前位置,并将当前位置改为父节点,继续向上比较。最后将插入元素插入到正确的位置。

示例1

#include <stdio.h>

void heapify(int a[], int i, int n) {
    int max = i, l = 2 * i, r = l + 1;
    if (l <= n && a[l] > a[max]) {
        max = l;
    }
    if (r <= n && a[r] > a[max]) {
        max = r;
    }
    if (max != i) {
        int temp = a[i];
        a[i] = a[max];
        a[max] = temp;
        heapify(a, max, n);
    }
}

void heapSort(int a[], int n) {
    int i;
    for (i = n / 2; i >= 1; i--) {
        heapify(a, i, n);
    }
    for (i = n; i > 1; i--) {
        int temp = a[1];
        a[1] = a[i];
        a[i] = temp;
        heapify(a, 1, i - 1);
    }
}

int main() {
    int a[] = {0, 5, 2, 4, 1, 3};
    int n = sizeof(a) / sizeof(int) - 1;
    heapSort(a, n);
    int i;
    for (i = 1; i <= n; i++) {
        printf("%d ", a[i]);
    }
    printf("\n");
    return 0;
}

执行结果:

1 2 3 4 5

示例2

#include <stdio.h>

void heapInsert(int a[], int n, int k) {
    int cur = n;
    a[cur] = k;
    while (cur > 1 && k > a[cur / 2]) {
        a[cur] = a[cur / 2];
        cur /= 2;
    }
    a[cur] = k;
}

int main() {
    int a[10] = {0};
    int n = 0;
    heapInsert(a, ++n, 5);
    heapInsert(a, ++n, 1);
    heapInsert(a, ++n, 4);
    heapInsert(a, ++n, 2);
    heapInsert(a, ++n, 3);
    int i;
    for (i = 1; i <= n; i++) {
        printf("%d ", a[i]);
    }
    printf("\n");
    return 0;
}

执行结果:

5 3 4 1 2

本站文章如无特殊说明,均为本站原创,如若转载,请注明出处:C语言数据结构之堆排序的优化算法 - Python技术站

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

相关文章

  • 使用C语言构建基本的二叉树数据结构

    下面是使用C语言构建二叉树数据结构的步骤和示例: 1. 定义二叉树结构体类型 定义一个二叉树的结构体,包含节点值、左右子节点等信息: typedef struct TreeNode { int val; struct TreeNode* left; struct TreeNode* right; } TreeNode; 2. 实现创建二叉树的函数 实现一个函…

    数据结构 2023年5月17日
    00
  • C++数据结构之搜索二叉树的实现

    C++数据结构之搜索二叉树的实现 搜索二叉树(Binary Search Tree, BST)是一种常见的数据结构,它支持快速地查找、插入和删除元素。本文将详细讲述如何用C++实现搜索二叉树。 一、搜索二叉树的定义 搜索二叉树是一种二叉树,它满足以下性质: 对于任意一个节点,其左子树中的所有节点都小于它,其右子树中的所有节点都大于它; 每个节点的左右子树也都…

    数据结构 2023年5月17日
    00
  • C++抽象数据类型介绍

    C++抽象数据类型介绍 什么是抽象数据类型? 抽象数据类型(Abstract Data Type,ADT),是数据类型的一个数学模型。它实现了数据类型的抽象过程,将数据与操作分离,使得操作具有独立性,而数据只作为函数参数和返回值存在。 举个例子,ADT可以定义一个栈(Stack),栈的实现需要以下操作: 初始化栈 压入数据 弹出数据 获取栈顶数据 检查栈是否…

    数据结构 2023年5月17日
    00
  • java 数据结构之栈与队列

    Java 数据结构之栈与队列 什么是栈? 栈是一种根据先进后出(LIFO)原则的数据结构,即最后压入的元素最先弹出。栈可以用数组或链表实现。栈的两个基本操作是 push(入栈)和 pop(出栈)。 栈的特性 只允许在栈的顶部插入和删除元素。 操作受限只能从一端进行。 元素的插入和删除时间复杂度都为 O(1)。 栈的示例 以下是使用 Java 语言实现栈的示例…

    数据结构 2023年5月17日
    00
  • 使用C语言详解霍夫曼树数据结构

    使用C语言详解霍夫曼树数据结构 什么是霍夫曼树 霍夫曼树是一种带权路径长度最短的树,也称为最优二叉树,它是优化编码的核心算法。 在霍夫曼树中,每个叶子节点对应一个字符,该节点的权值为该字符出现的次数。当然,字符可以是任何数据类型。生成霍夫曼树后,在对每个字符进行编码时,字符在霍夫曼树中的路径即为其编码。(一般规定,一条从根到叶子的路径上只出现0或1,从根到某…

    数据结构 2023年5月17日
    00
  • 剑指 Offer 33. 二叉搜索树的后序遍历序列(java解题)

    目录 1. 题目 2. 解题思路 3. 数据类型功能函数总结 4. java代码 5. 踩坑小记 递归调用,显示StackOverflowError 1. 题目 输入一个整数数组,判断该数组是不是某二叉搜索树的后序遍历结果。如果是则返回 true,否则返回 false。假设输入的数组的任意两个数字都互不相同。 参考以下这颗二叉搜索树: 5 / \ 2 6 /…

    算法与数据结构 2023年4月23日
    00
  • Redis五种数据结构在JAVA中如何封装使用

    Redis 是一款高性能的键值存储数据库,支持五种不同的数据结构:字符串(String)、哈希(Hash)、列表(List)、集合(Set)和有序集合(Sorted Set)。在Java中使用Redis需要封装对应的数据结构,本文将详细介绍如何封装Redis的五种数据结构。 封装Redis字符串数据结构 Redis字符串数据结构对应Java中的String类…

    数据结构 2023年5月17日
    00
  • 一些常见的字符串匹配算法

    作者:京东零售 李文涛 一、简介 1.1 Background 字符串匹配在文本处理的广泛领域中是一个非常重要的主题。字符串匹配包括在文本中找到一个,或者更一般地说,所有字符串(通常来讲称其为模式)的出现。该模式表示为p=p[0..m-1];它的长度等于m。文本表示为t=t[0..n-1],它的长度等于n。两个字符串都建立在一个有限的字符集上。 一个比较常见…

    算法与数据结构 2023年4月25日
    00
合作推广
合作推广
分享本页
返回顶部