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

    堆排序(Heap Sort)就是利用堆(假设利用大顶堆)进行排序的方法。它的基本思想是,将待排序的序列构造成一个大顶堆。此时整个序列的最大值就是堆顶的根节点。将它移走(其实就是将其与堆数组的末尾元素交换,此时末尾元素就是最大值),然后将剩余的n-1个序列重新构成一个堆,这样就会得到n个元素中的次大值。如此反复执行,便能得到一个有序序列了。

    核心代码

      1 #define LEFT  (2*nRootID+1)
      2 #define RIGHT (2*nRootID+2)
      3 
      4 void Adjust(int arr[], int len, int nRootID)
      5 {
      6     assert(arr!=NULL && len>0);
      7 
      8     while(1)
      9     {
     10         //两个孩子
     11         if(RIGHT < len)
     12         {
     13             //左比右大
     14             if(arr[LEFT] > arr[RIGHT])
     15             {
     16                 //左比父亲大
     17                 if(arr[LEFT] > arr[nRootID])
     18                 {
     19                     //交换
     20                     arr[LEFT] = arr[LEFT] ^ arr[nRootID];
     21                     arr[nRootID] = arr[LEFT] ^ arr[nRootID];
     22                     arr[LEFT] = arr[LEFT] ^ arr[nRootID];
     23 
     24                     //被交换位置作为新的调整位置
     25                     nRootID = LEFT;
     26                     continue;
     27                 }
     28                 else
     29                 {
     30                     break;
     31                 }
     32             }
     33             else
     34             {
     35                 //右比父亲大
     36                 if(arr[RIGHT] > arr[nRootID])
     37                 {
     38                     //交换
     39                     arr[RIGHT] = arr[RIGHT] ^ arr[nRootID];
     40                     arr[nRootID] = arr[RIGHT] ^ arr[nRootID];
     41                     arr[RIGHT] = arr[RIGHT] ^ arr[nRootID];
     42 
     43                     //被交换位置作为新的调整位置
     44                     nRootID = RIGHT;
     45                     continue;
     46                 }
     47                 else
     48                 {
     49                     break;
     50                 }
     51             }
     52         }
     53         //一个孩子
     54         else if(LEFT < len)
     55         {
     56             //左比父亲大
     57             if(arr[LEFT] > arr[nRootID])
     58             {
     59                 //交换
     60                 arr[LEFT] = arr[LEFT] ^ arr[nRootID];
     61                 arr[nRootID] = arr[LEFT] ^ arr[nRootID];
     62                 arr[LEFT] = arr[LEFT] ^ arr[nRootID];
     63 
     64                 //被交换位置作为新的调整位置
     65                 nRootID = LEFT;
     66                 continue;
     67             }
     68             else
     69             {
     70                 break;
     71             }
     72         }
     73         //没有孩子
     74         else
     75         {
     76             break;
     77         }
     78     }
     79 }
     80 
     81 void HeapSort(int arr[], int len)
     82 {
     83     int i;
     84 
     85     assert(arr!=NULL && len>0);
     86 
     87     //建堆
     88     //从最后一个父亲节点开始调整
     89     for(i=len/2-1; i>=0; --i)
     90     {
     91         //调整
     92         Adjust(arr, len, i);
     93     }
     94 
     95     //排序
     96     for(i=len-1; i>0; --i)
     97     {
     98         //堆顶和最后位置交换
     99         arr[i] = arr[i] ^ arr[0];
    100         arr[0] = arr[i] ^ arr[0];
    101         arr[i] = arr[i] ^ arr[0];
    102 
    103         //调整
    104         Adjust(arr, i, 0);
    105     }
    106 }

    函数Adjust()代码的优化

     1 void Adjust2(int arr[], int len, int nRootID)
     2 {
     3     int nMax;
     4 
     5     assert(arr!=NULL && len>0);
     6 
     7     for(nMax=LEFT; nMax<len; nMax=LEFT)
     8     {
     9         //两个孩子
    10         if(RIGHT < len)
    11         {
    12             if(arr[RIGHT] > arr[LEFT])
    13             {
    14                 nMax = RIGHT;
    15             }
    16         }
    17 
    18         //最大值和父亲进行比较
    19         if(arr[nMax] > arr[nRootID])
    20         {
    21             //交换
    22             arr[nMax] = arr[nRootID] ^ arr[nMax];
    23             arr[nRootID] = arr[nRootID] ^ arr[nMax];
    24             arr[nMax] = arr[nRootID] ^ arr[nMax];
    25 
    26             //被交换位置作为新的调整位置
    27             nRootID = nMax;
    28         }
    29         else
    30         {
    31             break;
    32         }
    33     }
    34 }

    算法分析:

      最好时间复杂度:O(nlog2(n))

      平均时间复杂度:O(nlog2(n))

      最坏时间复杂度:O(nlog2(n))

        空间复杂度:O(1)

          稳定性:不稳定

  • 相关阅读:
    git的使用(一)
    数据结构与算法 —— 二叉树 01
    数据结构与算法 —— 二叉树
    数据结构与算法 —— 链表linked list(06)
    数据结构与算法 —— 链表linked list(05)
    数据结构与算法 —— 链表linked list(04)
    数据结构与算法 —— 链表linked list(03)
    数据结构与算法 —— 链表linked list(02)
    Install sheild设置了Blue皮肤,但是有的窗口更改不了问题
    C# 进制转换
  • 原文地址:https://www.cnblogs.com/chen-cai/p/7744960.html
Copyright © 2011-2022 走看看