选择排序 - 堆排序

8 篇文章 0 订阅

直接选择排序

  首先在所有的记录中选出排序码最小的记录,把他与第一个记录交换,然后其余的记录内选出排序码最小的记录,与第二个记录交换......依次类推,直到查到所有的记录排完为止。

void main(){
    int a[10] = {77,100,99,22,11,44,33,66,55,88};
    selectSort(a,sizeof(a) / sizeof(int));
}
void selectSort(int a[],int length){
    int temp = 0;
    int k = 0;
    for(int i=0;i<length;i++){
        k = i;
        for(int j = i;j<length;j++){
            if(a[j] < a[k]){
               k = j;
            }
        }
        if(k!=i){
            temp  = a[i];
            a[i] = a[k];
            a[k] = temp;
        }
    }
}

堆排序

   堆是一颗完全二叉树--需要满足每个节点的值都不大于或不小于其父节点的值 -前者为大根堆后者为小根堆

 

将数组-变成二叉树,直接将数组元素从左到右依次放入节点即可,此二叉树物理储存方式就是数组
   *  调整堆:将二叉树初始化为堆,即让树的节点满足堆的特性
   *  排序:
   *    将堆的顶部节点数据与堆的最后一个节点(数组的尾部)交换-此时堆的底部节点(数组的最后一个元素)就是整个数列的最大值
   *    然后将堆的堆的底部节点(数组的最后一个元素)排除在堆之外(仍然在数组中,只是之后操作的索引数量减少1)
   *    然后再调整堆-交换-调整...


void main(){
  
    int a[10] = {77,100,99,22,11,44,33,66,55,88};
    heapSort(a,sizeof(a) / sizeof(int)-1);
}
void heapSort(int arr[],int len) {
   
   for (int i = len / 2 - 1; i >= 0; i--) { // 堆构造
        adjustHeap(arr, i, len);
            /*
             * 为什么只取数组中下半部分来初始化堆?
             *   从完成二叉树的第一个非叶子节点开始调整  从右至左-从下至上
             *    给定一个完全二叉树具有N个节点,若节点编号为i | 2*i + 1<=N 则其节点i有右子节点
             *    即N/2 - 1处有从右至左最后一个非叶子节点--从右至左便是第一个非叶子节点
             */
    }
    while (len >= 0) {
       
        // 将堆顶元素与尾节点交换后,长度减1,尾元素最大
        int temp = arr[0];
        arr[0] = arr[len];
        arr[len] = temp;
        
        len--;
        adjustHeap(arr, 0, len); // 再次对堆进行调整
    }
}

 

//调整堆

//针对一个节点和受其节点影响的节点-由上至下::因为构造堆时堆结构完全是乱的所以需要完全参与构造,,但之后调整堆只需调整受到影响的部分


void adjustHeap(int arr[],int i,int len){
    int left,right,j;
    int temp;
    while((left = 2*i+1)<=len){ //存在左孩子节点
         right = left + 1;//右孩子节点
         j = left;//j表示 左右节点较大的一个 默认为左孩子节点
         
         if (j < len && arr[left] < arr[right]){ // /*j < len起到是否存在右子节点的检查效果*/右节点大于左节点
                j++;// 当前把"指针"指向右节点
         }
           if (arr[i] < arr[j]){ // 将父节点与孩子节点交换(如果上面if为真,则arr[j]为右节点,如果为假arr[j]则为左节点)
               temp = arr[i];
               arr[i] = arr[j];
               arr[j] = temp;
         }
         else // 说明比孩子节点都大,直接跳出循环语句
            break;
        i = j;
    }
}

写出代码来有点困难,并不熟悉,有空再次编写^_^

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

雨中漫步t2

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值