堆排序

堆排序

定义

  1. 堆:符合以下两个条件之一的完全二叉树:
    (1)根节点的值 ≥ 子节点的值,这样的堆被称之为最大堆,或大顶堆;
    (2)根节点的值 ≤ 子节点的值,这样的堆被称之为最小堆,或小顶堆。

实现(数组)

堆排序的核心操作在于初始化堆和调整堆。

  1. 初始化堆:由于堆是一个完全二叉树,因此可以借用对完全二叉树的处理。数据以给定的顺序依次填入完全二叉树中,再进行初始化。默认顺序构造的堆不一定符合定义,自底向上考察每一个高度为2的子树,按条件处理。
  2. 调整堆:借由堆的性质获取堆顶元素并移出,将最后一个数据填入堆顶的空穴中,势必造成堆的崩坏,再自底向上进行调整。
#include <stdio.h>
#include <stdlib.h>
#include <string.h>

int checkMaxHeap(int* nums, int numsSize) {
    if(1 >= numsSize) return 0;
    int i, result;
    i = (numsSize-2)/2, result = 0;
    for(;i>=0;i--) {
        if(nums[i]<nums[2*i+1] || nums[i]<nums[2*(i+1)]) {
            result = -1;
            break;
        }
    }
    return result;
}

int checkMinHeap(int* nums, int numsSize) {
    if(1 >= numsSize) return 0;
    int i, result;
    i = (numsSize-2)/2, result = 0;
    for(;i>=0;i--) {
        if(nums[i]>nums[2*i+1] || nums[i]>nums[2*(i+1)]) {
            result = -1;
            break;
        }
    }
    return result;
}

void updateMaxHeap(int* nums, int numsSize) {
    int i,j;
    i = (numsSize-2)/2;
    for(;i>=0;i--) {
        if(2*(i+1)<numsSize) {
            if(nums[i]<nums[2*i+1] && nums[2*(i+1)]<nums[2*i+1]) {
                int tmp = nums[i];
                nums[i] = nums[2*i+1];
                nums[2*i+1] = tmp;
            }
            else if(nums[i]<nums[2*(i+1)] && nums[2*i+1]<nums[2*(i+1)]) {
                int tmp = nums[i];
                nums[i] = nums[2*(i+1)];
                nums[2*(i+1)] = tmp;
            }
        } else {
            if(nums[i]<nums[2*i+1]) {
                int tmp = nums[i];
                nums[i] = nums[2*i+1];
                nums[2*i+1] = tmp;
            }
        }
    }
    for(i=0;i<numsSize;i++) {
        printf("[%d]: %d\n",i,nums[i]);
    }
    printf("--------------------\n");
}

void updateMinHeap(int* nums, int numsSize) {
    int i,j;
    i = (numsSize-2)/2;
    for(;i>=0;i--) {
        if(2*(i+1)<numsSize) {
            if(nums[i]>nums[2*i+1] && nums[2*(i+1)]>nums[2*i+1]) {
                int tmp = nums[i];
                nums[i] = nums[2*i+1];
                nums[2*i+1] = tmp;
            }
            else if(nums[i]>nums[2*(i+1)] && nums[2*i+1]>nums[2*(i+1)]) {
                int tmp = nums[i];
                nums[i] = nums[2*(i+1)];
                nums[2*(i+1)] = tmp;
            }
        } else {
            if(nums[i]>nums[2*i+1]) {
                int tmp = nums[i];
                nums[i] = nums[2*i+1];
                nums[2*i+1] = tmp;
            }
        }
    }
    for(i=0;i<numsSize;i++) {
        printf("[%d]: %d\n",i,nums[i]);
    }
    printf("--------------------\n");
}

int main()
{
    int* nums = NULL;
    int numsSize = 6;
    nums = (int*)malloc(6*sizeof(int));
    memset(nums,0,6*sizeof(int));
    nums[0] = 3;
    nums[1] = 2;
    nums[2] = 1;
    nums[3] = 5;
    nums[4] = 6;
    nums[5] = 4;

    if(0 == checkMaxHeap(nums, numsSize)) printf("符合堆要求\n");
    else printf("不符合堆要求\n");

    updateMaxHeap(nums, numsSize);
    if(0 == checkMaxHeap(nums, numsSize)) printf("符合堆要求\n");
    else printf("不符合堆要求\n");

    updateMaxHeap(nums, numsSize);
    if(0 == checkMaxHeap(nums, numsSize)) printf("符合堆要求\n");
    else printf("不符合堆要求\n");

    free(nums);
    return 0;
}

参考资料

1.堆排序

posted @ 2022-01-22 23:35  万载志  阅读(89)  评论(0)    收藏  举报