堆排序
本质是选择排序 ,只是借助了完全二叉树的结构
#include<bits/stdc++.h>
using namespace std;
#define MAXSIZE 100
struct sqlist {
int arr[MAXSIZE];
int num;
};
void swap(sqlist* s, int i, int j)
{
int temp = s->arr[i];
s->arr[i] = s->arr[j];
s->arr[j] = temp;
}
void HeapAdjust(sqlist* s,int start ,int end) // 将非叶节点及其子树调整为大顶堆
{
int n = end / 2;
for (int i = n; i >0; i--)
for (int j = 2 * i; j <= end ; j *= 2) //顺着一路向下
{
if (j+1<=end && s->arr[j + 1] > s->arr[j]) j += 1;
if (s->arr[i] < s->arr[j]) swap(s, i, j);
}
}
void HeapSort(sqlist* s)
{
HeapAdjust(s,1,s->num);
for (int i = s->num; i > 1; i--)
{
swap(s, 1, i);
HeapAdjust(s,1,i-1 );
}
}
int main()
{
sqlist *s=new sqlist;
cin >> s->num;
for (int i = 1; i <= s->num; i++)
cin >> s->arr[i];
HeapSort(s);
for (int i = 1; i <=s->num; i++)
cout << s->arr[i] << ' ';
}
9
5 1 9 3 7 4 8 6 2
9 7 5 6 1 4 8 3 2
8 7 2 6 1 4 5 3 9
7 3 5 6 1 4 2 8 9
6 2 5 3 1 4 7 8 9
5 3 4 2 1 6 7 8 9
4 3 1 2 5 6 7 8 9
3 2 1 4 5 6 7 8 9
2 1 3 4 5 6 7 8 9
1 2 3 4 5 6 7 8 9
// end 是需要调整的最后一个结点 ,n则是需要调整的
void HeapAdjust(sqlist* s,int start ,int end) // 将非叶节点及其子树调整为大顶堆
{
int n = end / 2;
for (int i = n; i >0; i--)
for (int j = 2 * i; j <= end ; j *= 2) //顺着一路向下
{ // 一定要 j+1 <= end ,否则可能干扰到已经排好的部分
if (j+1<=end && s->arr[j + 1] > s->arr[j]) j += 1;
if (s->arr[i] < s->arr[j]) swap(s, i, j);
}
}
void HeapSort(sqlist* s)
{
HeapAdjust(s,1,s->num);
for (int i = s->num; i > 1; i--)
{
swap(s, 1, i);
HeapAdjust(s,1,i-1);
}
}
改进:减少交换次数
void HeapAdjust(sqlist* s,int start ,int end) // 将非叶节点及其子树调整为大顶堆
{
int n = end / 2 ,key ;
for (int i = n; i >0; i--)
{
key=s->arr[i] ;
for (int j = 2 * i; j <= end ; j *= 2) //顺着一路向下
{
if (j+1<=end && s->arr[j + 1] > s->arr[j]) j += 1;
if (key >= s->arr[j]) break ;
s->arr[i]=s->arr[j] ;
i=j ;
}
s->arr[i]=key ;
}
}
void HeapSort(sqlist* s)
{
HeapAdjust(s,1,s->num);
for (int i = s->num; i > 1; i--)
{
swap(s, 1, i);
HeapAdjust(s,1,i-1);
}
}