堆排序
思想:假设数组放入完全二叉树中,
1、初始化堆:调节父结点与子结点的大小。让所有的子结点都小于父结点。
2、将完全二叉树中的叶子结点和根结点进行互换后,继续调整堆。直至结束
#include<iostream>
#include<stdio.h>
#include<stdlib.h>
#include<random>
#include<time.h>
#include<sys/timeb.h>
using namespace std;
#define MAX 9
long getSystemTime()
{
struct timeb tb;
ftime(&tb);
return tb.time * 1000 + tb.millitm; //毫秒
}
void printArr(int arr[], int length)
{
for (int i = 0; i < length; i++)
{
printf("%d ", arr[i]);
}
printf("\n");
}
void swapElementme(int* a, int* b)
{
int temp =*a;
*a = *b;
*b = temp;
}
//堆排序
void heapSortme(int arr[], int length)
{
int mid = length / 2 - 1;
int lchild = mid * 2 + 1;
int rchild = mid * 2 + 2;
int max = mid;
//初始化堆
for (int i = mid; i < length; i--)
{
if (arr[i] < arr[lchild])
{
max = lchild;
}
if (arr[mid] > arr[rchild])
{
max = rchild;
}
if (max != mid)
{
swapElementme(&arr[mid], &arr[max]);
}
}
for (int i = 0; i < length; i++)
{
swapElementme(&arr[0], &arr[length - 1]);
heapSortme(arr, length);
}
}
void swapElement(int arr[], int a, int b)
{
int temp = arr[a];
arr[a] = arr[b];
arr[b] = temp;
}
/*
@param arr 待调整的数组
@param index 待调整的结点的下标
@param length 数组长度
*/
void heapAdjust(int arr[],int index, int length)
{
//保存当前结点的下标
int max = index;
//保存右孩子的数组下标
int lchild = index * 2 + 1;
//保存左孩子的数组下标
int rchild = index * 2 + 2;
if (lchild<length && arr[lchild]>arr[max])
{
max = lchild;
}
if (rchild<length && arr[rchild]>arr[max])
{
max = rchild;
}
if (max != index)
{
//交换两个结点
swapElement(arr, max, index);
heapAdjust(arr, max, length);
}
}
void heapSort(int arr[], int length)
{
//初始化堆
for (int i = length/2-1; i >=0; i--)
{
heapAdjust(arr, i, length);
}
//交换堆顶元素和最后一个元素
for (int i = length-1; i >= 0; i--)
{
swapElement(arr, 0,i);
heapAdjust(arr, 0, i);
}
}
int main()
{
int arr[] = { 4,2,8,0,5,7,1,3,9};
long t_start = getSystemTime();
printArr(arr,MAX);
heapSort(arr,MAX);
printArr(arr, MAX);
long t_end = getSystemTime();
printf("堆排序%d个元素,所需时间:%1d\n", MAX, t_end - t_start);
system("pause");
return 0;
}
运行结果: