几种常用的排序方法5--堆排序

堆排序

堆排序是一种原地排序,利用数据结构中的堆来管理数据。

(二叉)堆数据结构是一组数组对象,它可以被视为一个完全二叉树,树的每个节点与数组中存放该结点值得那个元素对用。

性质:

①父节点:i   左孩子::2*i    右孩子:2*i + 1       (注意:在计算机中可以用移位完成,左孩子是i<<1,右孩子是(i<<1) + 1)

②二叉堆有两种:最大堆和最小堆,这里以最大堆为例:除了根以外的每个结点i,有A[parent[i]] >= A[i],即每个结点的值最多与其父结点一样大。

③当用数组表示存储了n个元素的堆时,叶子结点的下标是[n/2]+1, [n/2]+2,......n。

堆排序算法的主要思想:

①首先初始化一个最大堆,此最大堆是一个无序区R[1,2,...n];

②根据最大堆的性质,根结点的元素R[1]一定是最大的元素,将R[1]与R[n]交换,得到新的有序区R[n]和无序区R[1,2,3...n-1];

③将无序区的元素重新再次调整为最大堆,重复②的做法,直到无序区只有一个元素。

 

堆排序的时间,主要由建立初始堆和反复重建堆这两部分的时间开销构成,它们均是通过调用Max_Heapify实现的。

堆排序比较适合数据较多的文件排序

 1 #include<stdio.h>
 2 #include<stdlib.h>
 3 #define MAXN 10000
 4 void Max_Heapify(int *A, int i, int n)
 5 {
 6      int largest;  //临时变量,存放数大的那个结点 
 7      int l = i << 1; //左孩子 
 8      int r = (i << 1) + 1; //右孩子   
 9      if(l <= n && A[l] > A[i])   //把大的数给largest 
10      {
11                largest = l;
12      } 
13      else largest = i;
14      if(r <= n && A[r] > A[largest])
15      {
16           largest = r;     
17      }
18      if(largest != i)
19      {
20           int temp = A[i];     //交换A[i]和较大的孩子 
21           A[i] = A[largest];    
22           A[largest] = temp;
23           Max_Heapify(A,largest,n);  //递归调用         
24      }
25 }
26 
27 void Build_Max_Heap(int *A, int n)
28 {//建立堆 
29  //子数组A[n/2,(n/2+1)....n]中的元素都是树中的叶子,看作只含一个元素的堆。
30  //对树中的每一个其它的结点调用一个Max_Heapify() 
31       for(int i = n/2 ; i >= 1; i--)
32       {
33            Max_Heapify(A,i,n);           
34       }
35 } 
36 
37 void HeapSort(int *A, int n) //堆排序 
38 {
39      Build_Max_Heap(A,n);
40      for(int i = n; i >= 1 ;i-- )
41      {
42            int t = A[i]; //交换A[0] 和A[i]的值,即将树根(最大的数)放入数组末 
43            A[i] = A[1];
44            A[1] = t;
45            Max_Heapify(A,1,i - 1); //从新调整最大堆    
46      }       
47 }
48 
49 int main()
50 {
51     int a[MAXN];
52     int n;
53     while(scanf("%d",&n) == 1 && n > 0)
54     {
55         int i;
56         for(i = 1; i <= n; i++)
57         {
58               scanf("%d",&a[i]);      
59         }     
60         HeapSort(a,n);      
61         for(i = 1; i <= n; i++)
62         {
63             printf("%d ",a[i]);        
64         }                            
65     }    
66     printf("\n");
67    // system("pause");
68     return 0;    
69 }

 

 

posted @ 2012-11-21 21:51  缓冲区溢出  阅读(288)  评论(0编辑  收藏  举报