首页 > 编程语言 > 详细

【二叉堆】二叉堆排序

时间:2020-02-26 11:20:48      阅读:86      评论:0      收藏:0      [点我收藏+]

二叉堆是近似的完全二叉树

二叉堆的特点是:

(1)父节点永远大于等于(或者小于等于)子节点

(2)每个结点的左子树和右子树又是一个二叉堆(递归)

进行堆排序需要的操作:

(1)堆化:反向调整使每个子叶都是大顶堆或者小顶堆

(2)按序输出元素:把堆顶的最末元素对调,然后调整堆顶元素

完整代码:

#include<stdio.h>
void MinHeap(int *A);
void MinHeapFixDown(int *A, int i,int n);
void  sort(int *A,int n);
int len(int *A);
void swap(int *A, int i, int j);

int main()
{
    int A[100]={1,2,5,6,4,3,2,9};
    int n=len(A); 
    sort(A,n);
    for(int i = 0; i< n; i++)
    {
        printf("%d",A[i]);
    }
    return 0;
}
//将数组堆化 
void MinHeap(int *A)
{
    int n=len(A);
    for(int i=n/2-1; i>0; i--)
    {
        MinHeapFixDown(A,i,n);
    }
 } 
 void MinHeapFixDown(int *A, int i,int n)//i记录为当前的结点 
 {
     int temp;
     //先找到左右孩子
     int left = 2*i+1;//在i是父节点的情况下,左子节点为2i+1
    int right = 2*i+2;
    
    //考虑在找左右孩子的时候下标是否越界
     if(left>=n) //如果左边都越界了对于二叉堆来说右边肯定也越界了,就直接返回,不进行调整 
     {
         return;//其实就是递归的边界 
     }
     int min = left;
     if(right>=n)//如果右孩子越界,那么两个孩子中较小的一定就是左孩子left 
     {
         min=left;
     }
     else
     {
         if(A[right]<A[left])
         {
             min=right;
         }
     }
     //以上操作将min指向了左右孩子中较小的那个
      
     //如果A[i]比两个孩子都小则不用调整
     if(A[i]<=A[min])//如果当前节点比左右孩子中较小的那个还小,那么就满足小顶堆,不用调整
     {
         return;//不用调整,直接返回 
      } 
     //否则,找到两个孩子中较小的,和i交换
     temp=A[i];
     A[i]=A[min];
     A[min]=temp;
     //小孩子那个位置的值发生了变化,i变成小孩子的那个位置(为了再从小孩子那个位置作为结点判断是否满足小顶堆),递归调整
    MinHeapFixDown(A, min,n);//再递归调用判断小孩子的位置是否需要调整 
  } 
void  sort(int *A,int n)
  {
      //先对数组A进行堆化
       MinHeap(A);
       for(int x = n-1; x>0; x--)//不断得缩小范围,不断把最后一个减去
       {
               //把堆顶元素和最后 一个元素对调
            swap(A,0,x);//交换数组A中的第一个元素和现在剩下的最后一个元素 
            //缩小堆的范围,对堆顶元素进行向下调整(循环)
            MinHeapFixDown(A,0,x-1);//对堆顶进行向下调整 
        }  
   } 
void swap(int *A, int i, int j)
{
       int temp;
       temp = A[i];
       A[i]=A[j];
       A[j]=temp;
} 
int len(int *A)
{
    int i = 0;
       int sum=0;
    while(A[i]!=\0)
    {
        sum++;
     } 
     return sum;
}

 

【二叉堆】二叉堆排序

原文:https://www.cnblogs.com/jessie99/p/12365684.html

(0)
(0)
   
举报
评论 一句话评论(0
关于我们 - 联系我们 - 留言反馈 - 联系我们:wmxa8@hotmail.com
© 2014 bubuko.com 版权所有
打开技术之扣,分享程序人生!