堆排序

先简单介绍下我对堆排序的理解
以升序为例子

int array[9] = {0,1,2,3,4,5,6,7,8} //这是一般写法

int array[9] = {            0,
                1,            2,
            3,      4,    5,       6 ,
    7,       8
}//这是堆排序时,初始数组可以看做这样一个二叉树

我将堆排序理解成将每一个父节点+左右子节点为一个单位进行排序例如: 0 1 2 ;1 3 4; 2 5 6 ; 3 7 8,其中0 1 2 3 都是对应结构中的父节点
排序最后一个节点开始 即先从 3 7 8 开始,再排序前几个节点,当节点编号小于0时结束.
这样我们就可以获得一个最大值 存储在a[0] ,这时候我们要建立一个数组用来存放得出的最大值,也就是第i轮循环后我们都要将a[0] 存储在另一个数组的第i - 1 - i个位置,最终会得到一个升序的数组.
PS:感觉和冒泡很像,只是将每轮2数排序改为每轮3数排序….
接下来看我的代码实现:


// 注释掉得内容有的是解释,还有一部分是之前没有实现的思路的代码,伪代码 不舍得删,大家将就着看
#import <Foundation/Foundation.h>
#import "Tree.h"

int main(int argc, const char * argv[])
{
    int n = 0;
    printf("请输入数组的长度:");
    scanf("%d", &n);


    int *array = NULL; //给数组分配空间  ps:其实这里不用指针更方便些,不过我这两天学指针啥啥都学傻了,下意识就用了
    array = malloc(n * 4);

    int *arrayPrint = NULL;
    arrayPrint = malloc(n * 4);//这个是最后用来存放结果的数组

    for (int i = 0; i < n; i++) {           //给数组赋值
        *(array + i) = arc4random()%100 + 1;
        printf("%-4d", *(array + i));
    }

    //利用小学知识 额 ...数学知识 可知 共有n / 2个节点  每个节点对应编号就为 n/2 (我是从0开始的,也可以从1开始编号)

    printf("\n**********************************\n");//打*分割下,

 //   int num = n / 2; //num为节点数

    for (int i = 0; i < n; i++) {           //外循环,每次循环获得一个最大值
        for (int j = (n - i) / 2 - 1; j >= 0; j-- ) {     //每个节点进行一次排序
            change((array + j), (array + 2 * j + 1), (array + 2 *j +2));
            // (array + j)是根节点的位置 (array + 2 * j + 1) 是左叶子的位置
            //(array + 2 * j + 1)是右叶子的位置
            //ps:就是这里用了指针反倒不好理解了,如果直接用数组还方便多了
        }
        printf("*******************************\n");//分隔开每次排序后的结果

       // printf("%-4d", *(array + i));

//        int temp = *(array) ;                     //正常的做法是将第一个数移到最后一位,然后数组总长度减1
//        *(array) = *(array + n - 1 - i);          //可是臣妾办不到啊!~!!!!!!~
//        *(array + n -1 - i) = temp;

        *(arrayPrint + n - 1 - i) = *(array);       //所以在下特地新建了一个数组arrayPrint来存放最大数
        *(array) = *(array + n - 1 - i);
        *(array + n - 1 - i) = 0;
    }

//  printf("\n");

    for (int i = 0; i < n; i++) {
        printf("%-4d", *(arrayPrint + i));
    }

}
#import <Foundation/Foundation.h>

void change(int *a, int *b, int *c);
#import "Tree.h"

void change(int *a, int *b, int *c){//这个函数的意义是将这三个数从大到小排序
                                    //只有三个数我就不冒泡了,
        if (*a < *b) {
        int temp = *a;
        *a = *b;
        *b = temp;
    }
    if (*a < *c) {
        int temp = *a;
        *a = *c;
        *c = temp;
    }
    if (*b < *c) {
        int temp = *b;
        *b = *c;
        *c = temp;
    }
    printf("%-4d %-4d %-4d\n", *a, *b, *c);
    //思考,这个排序好麻烦啊.有没有专门给三个数排序的好用的方法
};

结果展示
结果展示
其中被*分隔开的最上边一行是随机生成的数组,
中间的是每次外循环中各个树排序过后的结果,
其中可发现,如果一个树只有一个叶子,我就用0代替,这样就不会影响排序了

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值