先简单介绍下我对堆排序的理解
以升序为例子
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代替,这样就不会影响排序了