heapsort

来源:互联网 发布:肇庆市房地产数据 编辑:程序博客网 时间:2024/05/01 21:29
/* * szlHeapSort.h */#ifndef SZL_HEAP_SORT_H#define SZL_HEAP_SORT_Hvoid heapSort(int a[], int n);void siftDown(int a[], int root, int n);#endif

/* * szlSwap.h */#ifndef SZL_SWAP_H#define SZL_SWAP_H//交换两个数void swap(int *a, int *b);#endif
/* szlHeapSort.c * 堆是其节点值满足一定约束的完全二叉树; * 数组实现的n个节点的完全二叉树满足的性质,如果 * 1.用A[0..n-1]表示这棵树,那么 * (1)位置i的父节点为(i-1)/2; * (2)位置i的孩子节点为2*i+1及2*i+2; * (3)第一个叶子节点是n/2; * 2.用A[1..n]表示这棵树,那么 * (1)位置i的父节点为i/2; * (2)位置i的孩子节点为2*i及2*i+1; * (3)第一个叶子节点是n/2+1; */#include "szlHeapSort.h"#include "szlSwap.h"#include "stdio.h"/* * 将具有n个元素的数组a进行堆排序 */void heapSort(int a[], int n){  int i;  /*   * 以数组a为输入,建立一个堆   */  for(i=(n/2)-1; i>=0; i--){ // 从最后一个内部节点降序地访问到树根节点    siftDown(a,i,n); // 将每一个节点下沉,建立以位置i为根节点的子堆,sub heap  }    /*   * 将树根节点和最后一个叶子节点交换;   * 并将堆的大小减少1;   * 然后调整树根,以保持堆序;   * 循环,直至访问到第2个元素   */  for(i=n-1; i>=1; i--){    swap(&a[0],&a[i]);    siftDown(a,0,i);  }}/* * 将root位置的节点在大小为n的堆a中调整,以保持堆序 */void siftDown(int a[], int root, int n){  int done, maxChild;  done = 0;  while(!done){    if(root*2+2<=n-1){ //如果root存在左孩子和右孩子  if(a[root*2+1]>a[root*2+2]){ //max记住较大的孩子        maxChild=root*2+1;  }  else{    maxChild=root*2+2;  } }else if(root*2+1==n-1){ // 如果root有左孩子  maxChild=root*2+1;}else{ //没有孩子节点  maxChild = root; // 标记root为最大的元素}if(a[root] < a[maxChild] ){ // 将最大的元素和root位置的元素交换      swap(&a[maxChild],&a[root]);  root=maxChild; //以较大的孩子为根节点继续往下访问    }else{  done=1;}  }}


 

/* * szlSwap.c */#include "szlSwap.h"void swap(int *a, int *b){int t=*a;*a=*b;*b=t;}


 更为简洁的版本:

/* * heapsort.c */#include <stdio.h>#define N 30void swap (int * p, int * q){    if (! (p == q)){        * p ^= * q;        * q ^= * p;        * p ^= * q;    }}void sift_down (int a[], int i, int n){    int max = i;    if ( 2*i+2 <= n-1){        max = a[2*i+1] > a[2*i+2] ? (2*i+1) : (2*i+2);    }    else if (2*i+1 == n-1){        max = 2*i+1;    }    if (a[max] > a[i]){        swap (&a[i], &a[max]);        sift_down (a, max, n); /* recursion */    }}void build_heap (int a[], int n){    int i;    for (i=(n-1)/2; i>=0; i--){        sift_down (a, i, n);    }}void heapsort (int a[], int n){    int i;    build_heap (a, n);    for (i=n-1; i>0; i--){        swap (&a[0], &a[i]);        sift_down (a, 0, i);    }}int main (int argc, char ** argv){    int n;    int i;    int a[N];#ifdef DEBUG1    freopen ("in.txt", "r", stdin);#endif    scanf ("%d", &n);    for (i=0; i<n; i++)        scanf ("%d", &a[i]);    heapsort (a, n);    for (i=0; i<n; i++)        printf ("%d ", a[i]);    #ifdef DEBUG1    fclose (stdin);#endif    return 0;}




 

原创粉丝点击
热门问题 老师的惩罚 人脸识别 我在镇武司摸鱼那些年 重生之率土为王 我在大康的咸鱼生活 盘龙之生命进化 天生仙种 凡人之先天五行 春回大明朝 姑娘不必设防,我是瞎子 幸福树树干烂了怎么办 花椒树树叶掉落枝干发黑怎么办 茉莉枝干变干了怎么办 冲风了头蒙怎么办 不小心把腰扭了怎么办 白衣服发霉有小黑点怎么办 佛肚竹的枝叶都枯了怎么办 山竹一天吃多了怎么办 水养竹子叶子发黄怎么办 龙竹的竹杆黄了怎么办 散尾竹叶子发黑怎么办 给姐姐打工不发工资怎么办? 水培红掌叶子发黄怎么办 盆竹的叶尖发黄怎么办 养富贵竹水里怎么生小虫怎么办 盆栽金银花叶子全部落掉怎么办 荷花竹根部烂了怎么办 水培绿萝叶子发黄怎么办 大早上的公鸡老打鸣怎么办 紫吊兰叶子变绿怎么办 芙桑花叶子发黄怎么办 长春花长得太高怎么办 四季梅叶子蔫了怎么办 吸财树叶子蔫了怎么办 民族团结手抄报间单有漂亮怎么办 鹦鹉尾巴毛掉了怎么办 羊绒衫领子打太大了怎么办 内裤洗了还有一股味道怎么办 月经下不来内裤上总有脏东西怎么办 夏天外衣薄露出内衣怎么办 金毛体味很重怎么办 直筒连衣裙太短怎么办 托班社会下雨了怎么办 托班下雨了怎么办教案 吃鸡界面有鼠标怎么办 老年机成英语了怎么办 手机成了英语了怎么办 塑料袋融化粘到衣服上怎么办 厕所被卫生纸堵了怎么办 钻石画的胶不粘了怎么办 客厅沙发选大了怎么办