内部排序之堆排序的实现

时间:2025-11-01 21:24:22 C语言

内部排序之堆排序的实现

  堆排序(Heap Sort)只需要一个记录大小的辅助空间,每个待排序的记录仅占有一个存储空间。下面小编为大家整理了内部排序之堆排序的实现,希望能帮到大家!

  (1)基本概念

  a)堆:设有n个元素的序列:

  {k1, k2, ..., kn}

  对所有的i=1,2,...,(int)(n/2),当满足下面关系:

  ki≤k2i,ki≤k2i+1

  或 ki≥k2i,ki≥k2i+1

  这样的序列称为堆。

  堆的两种类型:

  根结点最小的堆----小根堆。

  根结点最大的堆----大根堆。

  根结点称为堆顶,即:在一棵完全二叉树中,所有非叶结点的值均小于(或均大于)左、右孩子的值。

  b)堆排序:是一种树型选择排序,特点是,在排序过程中,把R[1..n]看成是一个完全二叉树的存储结构,利用完全二叉树双亲结点和孩子结点的内在关系,在当前无序区中选择关键字最大(最小)的记录。

  (2)堆排序步骤:

  1、从k-1层的最右非叶结点开始,使关键字值大(或小)的记录逐步向二叉树的上层移动,最大(或小)关键字记录成为树的根结点,使其成为堆。

  2、逐步输出根结点,令r[1]=r[i](i=n,,n-1,...,2),在将剩余结点调整成堆。直到输出所有结点。我们称这个自堆顶到叶子的调整过程为“筛选”。

  (3)要解决的两个问题:

  1、如何由一个无序序列建成一个堆;

  2、输出一个根结点后,如何将剩余元素调整成一个堆。

  将一个无序序列建成一个堆是一个反复“筛选”的过程。若将此序列看成是一个完全二叉树,则最后一个非终端结点是第floor(n/2)个元素,由此“筛选”只需从第floor(n/2)个元素开始。

  堆排序中需一个记录大小的辅助空间,每个待排的记录仅占有一个存储空间。堆排序方法当记录较少时,不值得提倡。当n很大时,效率很高。堆排序是不稳定的。

  堆排序的算法和筛选的算法如第二节所示。为使排序结果是非递减有序排列,我们在排序算法中先建一个“大顶堆”,即先选得一个关键字为最大的记录并与序列中最后一个记录交换,然后对序列中前n-1个记录进行筛选,重新将它调整为一个“大顶堆”,然后将选得的一个关键字为最大的记录(也就是第一个元素)与当前最后一个记录交换(全局看是第n-1个),如此往复,直到排序结束。由到,筛选应按关键字较大的孩子结点向下进行。

  堆排序的算法描述如下:

  用C语言代码实现如下:

  复制代码 代码如下:

  #include "iostream"

  using namespace std;

  #define MAXSIZE 20

  typedef struct

  {

  int key;

  /pic/p>

  }RedType;

  typedef struct

  {

  RedType r[MAXSIZE+1];

  int length;

  }Sqlist;

  typedef Sqlist HeapType; /pic/p>

  void HeapAdjust(HeapType &H,int s,int m) /pic/p>

  {

  int j;

  RedType rc;

  rc=H.r[s];

  for(j=2*s;j<=m;j*=2) /pic/p>

  {

  if(j<m && (H.r[j].key<H.r[j+1].key)) /pic/p>

  ++j;

  if(rc.key>=H.r[j].key) /pic/p>

  break;

  H.r[s]=H.r[j]; /pic/p>

  s=j;

  }

  H.r[s]=rc; /pic/p>

  }

  void HeapSort(HeapType &H) /pic/p>

  {

  int i;

  for(i=H.length/2;i>0;--i) /pic/2个元素

  HeapAdjust(H,i,H.length);

  for(i=H.length;i>1;--i)

  {

  H.r[0]=H.r[1]; /pic/p>

  H.r[1]=H.r[i];

  H.r[i]=H.r[0];

  HeapAdjust(H,1,i-1); /pic/p>

  }

  }/pic/p>

  void InputL(Sqlist &L)

  {

  int i;

  printf("Please input the length:");

  scanf("%d",&L.length);

  printf("Please input the data needed to sort:n");

  for(i=1;i<=L.length;i++) /pic/p>

  scanf("%d",&L.r[i].key);

  }

  void OutputL(Sqlist &L)

  {

  int i;

  printf("The data after sorting is:n");

  for(i=1;i<=L.length;i++)

  printf("%d ",L.r[i].key);

  printf("n");

  }

  int main(void)

  {

  Sqlist H;

  InputL(H);

  HeapSort(H);

  OutputL(H);

  system("pause");

  return 0;

  }

  不使用上面的结构体的另外一种方法如下:

  复制代码 代码如下:

  /*

  *堆排序

  */

  #include "iostream"

  using namespace std;

  #define N 10

  int array[N];

  void man_input(int *array)

  {

  int i;

  for(i=1;i<=N;i++)

  {

  printf("array[%d]=",i);

  scanf("%d",&array[i]);

  }

  }

  void mySwap(int *a,int *b)/pic/p>

  {

  int temp;

  temp=*a;

  *a=*b;

  *b=temp;

  }

  void heap_adjust(int *heap,int root,int len) /pic/p>

  {

  int i=2*root;

  int t=heap[root];

  while(i<=len)

  {

  if(i<len)

  {

  if(heap[i]<heap[i+1])

  i++;

  }

  if(t>=heap[i])

  break;

  heap[i/2]=heap[i];

  i=2*i;

  }

  heap[i/2]=t;

  }

  void heapSort(int *heap,int len) /pic/p>

  {

  int i;

  for(i=len/2;i>0;i--) /pic/2个元素

  {

  heap_adjust(heap,i,len);

  }

  for(i=len;i>=1;i--)

  {

  mySwap(heap+i,heap+1); /pic/p>

  heap_adjust(heap,1,i-1); /pic/p>

  }

  }

  void print_array(int *array,int n)

  {

  int k;

  for(k=1;k<n+1;k++)

  {

  printf("%dt",array[k]);

  }

  }

  int main(void)

  {

  man_input(array);

  heapSort(array,N);

  printf("nAfter sorted by the heap_sort algorithm:n");

  print_array(array,N); /pic/p>

  system("pause");

  return 0;

  }

【内部排序之堆排序的实现】相关文章:

C#排序算法之堆排序11-16

堆排序算法及用C++实现基于最大堆的堆02-12

java堆排序的算法思想的分析11-29

php如何实现快速排序09-11

如何实现归并排序03-14

分析php选择排序法实现数组排序的方法12-13

希尔排序(C语言实现)01-26

冒泡排序(C语言实现)12-01

C#排序算法之快速排序01-07