堆排序(Heap Sort)算法学习 –

在课程在实地工作的的互插,堆(heap)的思惟,次要关涉两个接:

  • 首先消息结构,逻辑是首先结合的的二叉树两,铺子是首先瞄准大厦(二叉堆)。
  • 渣滓搜集和记得区,是记得的地域可以课程的软件零碎。

本文所说的堆,指前。

工夫的堆排序复杂的事物为O(nlgn),在同上的工夫复杂的事物的彻底地排序。但在现实用功中,we的领地格形式冲向应用彻底地排序比堆排序。这是由于首先澄清的达到预期的目的彻底地排序,它通常比堆排序的机能更。。堆排序的次要用途,在小修道院院长队列的构成和处置接。更,设想必要计算(如小修道院院长级队列,假如最大或最小元素统计表。,唯一的限定的的拔出查问),堆是首先正是公正的消息结构。

初步

堆大厦表现普通用,拿 … 来说,大厦的扣押是扣押(a),对大厦说得中肯元素数堆堆(一)。普通说来,HeapSize(A) <= Length(A),由于大厦A当中能够有一些元素不在堆中。

设想i杂种的说得中肯杂种的i下标大厦。

  • 母(我) : return Floor(i/2); 我的父杂种的,Floor(i)表现比i小的最大完整的。
  • 左(i) : return 2*i; 我的左子杂种的
  • 右(i) : return 2*i+1; 我的右子杂种的

n个元素的高位是一堆一 楼(LGN)。

栈的根本用双手触摸、举起或握住

  • MaxHeapify( A, i ):
  • 保存堆的领地权。设想大厦和我。,先决条件以左(i)和右(i)为根蝴蝶结的摆布两棵子树都早已是最大堆,i杂种的的值能够缺席其子杂种的。对准杂种的获名次的我。

  • BuildMaxHeap( A ):
  • 从首先事先调整的大厦创办最大堆。子阵 底部(n/2) 1 …. … n ]元素树说得中肯叶杂种的(结合的的根本领地权。从引用标志 难以完成的限额(n / 2)至1,对每个元素举行maxheapify,最后的腰槽首先最大堆。

  • 堆排序 HeapSort( A ):
  • 堆排序算法的根本思惟是,大厦A是为最大堆建立的,继互通式立体交叉堆(最大根元素)和最后的一张页杂种的x,X将取代从堆栈中构成新的堆A1,继反复前文举措,唯一的首先杂种的,直到堆。

  • 小修道院院长队列算法——筹集元素的值(小修道院院长级) : HeapIncreaseKey( A, i, key )
  • 在(值)后头添加首先元素小修道院院长级,元素一定向上自己谋生,为了保存堆的领地权。

  • 小修道院院长级队列算法拔出首先元素 Insert( S, x ) 拔出X元素进入小修道院院长队列的。
  • 其次要思惟是,叠后的最后的一张页杂种的,为新的叶杂种的无穷大延伸,继,它筹集了x的值。

堆排序的达到预期的目的规律

c语风说得中肯堆排序

#include 
#include 

void HeapSort(int num[],int 胶料)
void BuildHeap(int num[] ,int 胶料)
void PercolateDown(int num[] , int index,int 胶料)
void PrintHeap(const char* strMsg,int array[],int nLength); 
void 掉换(int num[] , int v, int u);

int 次要(int argc, char *argv[])
{
  int data[13]={8,5,4,6,13,7,1,9,12,11,3,10,2};
  HeapSort(消息,13);
  
  零碎(暂时的停顿)
  return 0;
}


void HeapSort(int num[] ,int 胶料)
{
    int i;
    int iLength=size;
    
    PrintHeap("Befor Sort:",num,iLength);
    
    BuildHeap(num,胶料)// 堆小堆   
    
    for (i = iLength - 1; i >= 1; i--) {   
        掉换(Num, 0, i);// 互通式立体交叉   
        size--;// 使还原胶料的无论何时交流   
        PercolateDown(num, 0,胶料)// 新的过滤用双手触摸、举起或握住的首先地区 
        PrintHeap("Sort Heap:",num,iLength);  
    }
}

// 建堆办法,唯一的创办了线形的工夫   
void BuildHeap(int num[] ,int 胶料) { 
    int i; 
    for (i = size / 2 - 1; i >= 0; i--) {// 半载的杂种的(解说为从最后的首先非叶缺席,每个父杂种的对准到更有理的最小堆)   
        PercolateDown(num, i,胶料)// 举行下滤用双手触摸、举起或握住
        PrintHeap("Build heap:",num,胶料)
    }   
}
    
// 过滤用双手触摸、举起或握住是在刚过去的数,直到数缺席左、右杂种的,滤波器是STO   
void PercolateDown(int num[] , int index,int 胶料) {   
    int min;// 设置最小圆点。   
    while (引用标志 * 2 + 1<胶料) {// 设想该数有左杂种的,则假设左杂种的最小   
        min = index * 2 + 1;// 获取左杂种的的下标   
        if (引用标志 * 2 + 2<胶料) {// 设想该数还有右杂种的   
            if (num[min] > Num [引用 * 2 + 2]) {// 在左,从最小的杂种的   
                min = index * 2 + 2;// 小的右杂种的,翻新最小的标点标   
            }   
        }   
        // 在区别数和最小工夫。,   
        if (Num [引用] < num[min]) {// 设想index最小,   
            break;// 停止下滤用双手触摸、举起或握住   
        } else {   
            掉换(Num, index, min);// 互通式立体交叉两个数,让大数往下沉   
            index = min;// 翻新index的标点   
        }   
    }// while   
}
    
// 事先调整大厦互通式立体交叉两个数的获名次   
void 掉换(int num[] , int v, int u) {  
    int temp = num[v];   
    num[v] = num[u];   
    num[u] = temp;   
}   

void PrintHeap(const char* strMsg,int array[],int nLength)
{
     int i;
     printf("%s",strMsg);
     for(i=0;i

Here is the C language,在首先小小的更衣:

#include 
#include 

void HeapSort(int num[],int 胶料)
void BuildHeap(int num[] ,int 胶料)
void PercolateDown(int num[] , int index,int 胶料)
void PrintHeap(const char* strMsg,int array[],int nLength); 
void 掉换(int num[] , int v, int u);

int 次要(int argc, char *argv[])
{
  /* 线形的记得中序遍历总算为二叉树的大厦。 */
  int data[13]={8,5,4,6,13,7,2,9,12,11,3,10,1};
  HeapSort(消息,13);
  
  零碎(暂时的停顿)    
  return 0;
}


void HeapSort(int num[] ,int 胶料)
{
    int i;
    int iLength=size;
    
    PrintHeap("Befor Sort:",num,iLength);
    
    BuildHeap(num,胶料)// 堆小堆   
    
    for (i = iLength - 1; i >= 1; i--) {   
        掉换(Num, 0, i);// 互通式立体交叉   
        size--;// 使还原胶料的无论何时交流   
        PercolateDown(num, 0,胶料)// 新的过滤用双手触摸、举起或握住的首先地区 
        PrintHeap("Sort Heap:",num,iLength);  
    }
}

/* 建堆办法,唯一的创办了线形的工夫;
   成桩总算:该大厦的第首先元素(即根)是领地EL的最低消费,引用缺席接近size/2-1的其它元素(即其它非页杂种的)的值都是其在哪里子树的最低消费 */   
void BuildHeap(int num[] ,int 胶料) { 
    int i; 
    从最后的首先非叶杂种的开端,在附近每个非页杂种的到根型对准,确保每个根杂种的的子树说得中肯最低消费
    for (i = size / 2 - 1; i >= 0; i--) {   
        PercolateDown(num, i,胶料)// 举行下滤用双手触摸、举起或握住
        PrintHeap("Build heap:",num,胶料)
    }   
}
    
/* 过滤用双手触摸、举起或握住是在刚过去的数,直到数缺席左、右杂种的,滤波器是STO。
   即对某个根杂种的的值举行获名次下来对准,该值缺席左子杂种的。;
   If the node is a leaf node,不克不及在环绕 */
void PercolateDown(int num[] , int index,int 胶料) {   
    int min;// 设置最小圆点。   
    while (引用标志 * 2 + 1<胶料) {// 设想该数有左杂种的,则假设左杂种的最小   
        min = index * 2 + 1;// 获取左杂种的的下标   
        if (引用标志 * 2 + 2<胶料) {// 设想该数还有右杂种的   
            if (num[min] > Num [引用 * 2 + 2]) {// 在左,从最小的杂种的   
                min = index * 2 + 2;// 小的右杂种的,翻新最小的标点标   
            }   
        }   
        // 在区别数和最小工夫。,   
        if (Num [引用] < num[min]) {// 设想index最小,   
            break;// 停止下滤用双手触摸、举起或握住   
        } else {   
            掉换(Num, index, min);// 互通式立体交叉两个数,让大数往下沉   
            index = min;// 翻新index的标点   
        }   
    }// while   
}
    
// 事先调整大厦互通式立体交叉两个数的获名次   
void 掉换(int num[] , int v, int u) {  
    int temp = num[v];   
    num[v] = num[u];   
    num[u] = temp;   
}   

void PrintHeap(const char* strMsg,int array[],int nLength)
{
     int i;
     printf("%s",strMsg);
     for(i=0;i