利用堆结构和二叉树的一些性质来完成数据的排序。
堆结构:
完全二叉树
在这个树中每个结点对应于原 始数据的一个记录,并且每个结点应满足以 下条件:
• 如果 按照从小 到大的 顺序排序,要求非叶结点的数据要大于或等于其左 、 右子结点的数据。
• 如果按照从大到 小 的 顺序排序,要求非叶结点的数据要小 于或等于其左 、 右子结点的数据。
这里以 从小 到大的 顺序进行排序为例进行介绍。 从堆结构的定义可以 看出,对结点的左子结点和 右子结点的大小 没有要求, 只 规定父结点和子结点数据之间必 须满足的大小 关系 。这 样 ,如果要求按照从小 到大的 顺序输出数据时, 则 堆结构的根结点为要求的最大值。
堆排序过程:
反复两个过程:构造堆结构和堆排序输出
构造堆结构就是把原 始的 无序数据按前面堆结构的定义进行调 整。 首先 , 需要将原始的无序数据放置到一个完全二叉树的 各个结点中,这可以 按照前面介绍的方法来实现。
然 后 , 由 完全二叉树的 下层向 上层逐层进行父子结点的数据进行比较, 使父结点的数据大于子结点的数据。这里需要使用 筛运算进行结点数据的 调 整, 直到使所有结点最后满足堆结构的条件为止 。 筛运算主要针对非叶结点进行调 整。
例如,对于一个非叶结点 Ai,这里假定 鴻的 左 子树和 右 子树均 已 进行筛运算,也就是说其左子树和 右子树均 已构成堆结构。 下 面,对 鴻 进行 筛 运 算, 操作步骤如 下 :
( 1 ) 比较Ai的 左 子树和 右子树的最大值, 将 最大值 放 在 Aj中。
(2) 将Ai的数据与 Aj 的数据进行 比较 ,如果 Ai 大于等于 Aj , 表示以 Ai为根的子树已构成堆结构,便可以 终止筛运算。
(3) 如果 Ai小 于 Aj , 则将 Ai与 Aj互 换 位 置 。
(4) 经 过 第 (3 ) 步后 ,可 能 会破 坏 以Ai为根的 堆 , 因 为 此时 Ai 的值为 原 来的 Aj 。 下 面 以 Aj为根重复前面的 步骤, 直到 满足堆结构的定义,也就是父结点数据大于子结点。这 样 ,以 Aj为根的子树就被调 整为一个堆。在执行筛运算时,值较小 的数据将被逐层下移。
// HeapSort.cpp : Defines the entry point for the console application.
//
#include "stdafx.h"
#include<IOSTREAM>
#include<CSTDIO>
#include<CSTDLIB>
#include<CSTRING>
#include<CTIME>
using namespace std;
#define SIZE 10
void HeapSort(int a[], int n)
{
int i, j, h, k;
int t;
for (i = n / 2-1; i >= 0; i--)
{
while(2 * i + 1 < n)
{
j = 2 * i + 1;
if ((j + 1) < n)
{
if (a[j] < a[j +1])
{
j++;
}
}
if (a[i] < a[j])
{
t = a[i];
a[i] = a[j];
a[j] = t;
i = j;
}
else
{
break;
}
}
}
cout<<"org array Heap: "<<endl;
for (h = 0; h < n; h++)
{
cout<<a[h]<< " ";
}
cout<<endl;
for (i = n - 1; i > 0; i--)
{
t = a[0];
a[0] = a[i];
a[i] = t;
k = 0;
while(2 * k + 1 < i)
{
j = 2 * k + 1;
if ((j + 1) < i)
{
if(a[j] < a[j +1])
{
j++;
}
}
if (a[k] < a[j])
{
t = a[k];
a[k] = a[j];
a[j] = t;
k = j;
}
else
{
break;
}
}
cout<<"step "<< n - i << " sort"<<endl;
for (h = 0; h < n; h++)
{
cout<<a[h]<< " ";
}
cout<<endl;
}
}
int main(int argc, char* argv[])
{
int array[SIZE], i;
srand(time(NULL));
for (i = 0;i < SIZE; i++)
{
array[i] = rand() / 10000 + 100;
}
cout<<"before sort -------------"<<endl;
for (i = 0; i < SIZE; i++)
{
cout<<array[i]<<" ";
}
cout<<endl;
HeapSort(array, SIZE);
cout<<"Sort: ------------------"<<endl;
for (i = 0; i < SIZE; i++)
{
cout<<array[i]<<" ";
}
cout<<endl;
getchar();
return 0;
}
before sort -------------
101 100 100 102 100 100 102 102 101 100
org array Heap:
102 102 102 101 100 100 100 100 101 100
step 1 sort
102 101 102 101 100 100 100 100 100 102
step 2 sort
102 101 100 101 100 100 100 100 102 102
step 3 sort
101 101 100 100 100 100 100 102 102 102
step 4 sort
101 100 100 100 100 100 101 102 102 102
step 5 sort
100 100 100 100 100 101 101 102 102 102
step 6 sort
100 100 100 100 100 101 101 102 102 102
step 7 sort
100 100 100 100 100 101 101 102 102 102
step 8 sort
100 100 100 100 100 101 101 102 102 102
step 9 sort
100 100 100 100 100 101 101 102 102 102
Sort: ------------------
100 100 100 100 100 101 101 102 102 102
本文介绍了堆排序的基本概念,包括堆结构的特点及如何利用这些特点完成数据排序的过程。通过具体的筛运算步骤说明了如何构建并调整堆结构,最终实现从小到大的排序。
31万+

被折叠的 条评论
为什么被折叠?



