直接选择排序
首先在所有的记录中选出排序码最小的记录,把他与第一个记录交换,然后其余的记录内选出排序码最小的记录,与第二个记录交换......依次类推,直到查到所有的记录排完为止。
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;
}
}
写出代码来有点困难,并不熟悉,有空再次编写^_^