zoukankan      html  css  js  c++  java
  • 堆排序

    堆排序用到的是完全二叉树的性质,所以在看这篇文章之前先学习完全二叉树。


    http://baike.baidu.com/link?url=HUZLyRNtNhAUzf7rgffW3IHkPbNQF_0vO63EvTKZBgYztrMz02B2_-PlCV5eFg6J8y8w8sHEu4Bd7bZVOXozaK


    那么,学会了完全二叉树,现在就可以学习堆排序了。

    个人认为,堆排序是插入排序和快排思想的联合,所以读者可以先学会插入排序和快排。

      插入排序:每次选出带排序序列的最大值,加入已排好序的序列;

      快排:在待排序序列中选择一个记录,让它左边的都比它小,右边的都比它大,如此递归。

    思考:

      对于插入排序,时间复杂度主要在选择最大值的过程中。有没有一种方法可以用更少的时间就选出最大值呢?

      对于快速排序,如果用完全二叉树存储,让根节点比左子树大,比右子树也大,那这个根节点不就是最大值吗?

    两相结合,堆排序应运而生,而核心就是完全二叉树的性质。下面可以看看堆排序相关的概念,有助于理解。


    http://baike.baidu.com/link?url=Fc3__n67naxdKu_l7MzWi6WCn4QbbJESFSKiJUvvO-CzszGyoqv0coneADUg6DjcJEAVpymvhqwm8qRe9gEYSK


    下面是堆排序的代码:

     1 #include<stdio.h>
     2 void creatheap(int *a,int n,int i)  //整理堆的函数,包括三个参数,数组首地址,数组元素个数,要处理的结点编号 
     3 {
     4  if (i*2+1>n)   //如果 这个结点没有右孩子 
     5  {
     6   if (i*2>n) return;  //如果再没有左孩子,直接return 
     7   else    //如果有左孩子,就比较这个结点和左孩子是否需要交换 
     8   {
     9    if (a[i*2]>a[i])
    10    {
    11     a[0]=a[i];
    12     a[i]=a[i*2];
    13     a[i*2]=a[0];
    14     creatheap(a,n,2*i);  //递归左孩子 
    15    }
    16    else return;  //不需要交换的话直接return 
    17   }
    18  }
    19  else //如果有右孩子(那么肯定有左孩子啦~) 
    20  {
    21   if (a[i*2+1]<=a[i]&&a[i*2]<=a[i]) return; //经过比较左右孩子都不需要交换,说明这个堆不用处理了,return 
    22   else{  //否则,这个堆需要处理 
    23    int maxi=i*2;  //下面分析需要处理左孩子还是右孩子 
    24    if (a[i*2+1]>a[i*2]) maxi++;
    25    a[0]=a[i];
    26    a[i]=a[maxi];
    27    a[maxi]=a[0];
    28    creatheap(a,n,maxi);  //递归需要处理的那个 
    29   }
    30  }  //这样就完成了一次整理 
    31 }
    32 int main()
    33 {
    34  int b[101]={0};
    35  int n;
    36  scanf("%d",&n);
    37  int i;
    38  for (i=1;i<=n;i++)
    39  {
    40   scanf("%d",b+i);
    41  }
    42  for (i=n/2;i>=1;i--)  //对非叶子结点递减整理,n/2是第一个非叶子结点的编号 
    43  {
    44   creatheap(b,n,i);
    45  }
    46  //这样整理完之后目前这个数组是一个堆了 可以确定的是第一个元素b[1]一定是最值 
    47  int k=n;
    48  while (n!=1)
    49  {
    50   b[0]=b[1];
    51   b[1]=b[n];
    52   b[n]=b[0];
    53   n--;
    54   creatheap(b,n,1);  //把b[1]移到末尾,然后同理整理前n-1个元素,直到n=1 
    55  }
    56  for (i=1;i<=k;i++)  //堆排序完成 
    57  {
    58   printf("%d ",b[i]);
    59  }
    60  return 0;
    61 }
  • 相关阅读:
    poj3348 Cow
    poj3348 Cow
    日常。。。强行续
    日常。。。又又续
    日常。。。又又续
    日常。。。又续
    内存检索
    MyLayer MyScene
    冒泡排序
    Array数组的排序与二分查字法
  • 原文地址:https://www.cnblogs.com/itlqs/p/4750162.html
Copyright © 2011-2022 走看看