来看排序分类图:
这篇文章和大家分享选择排序,既简单选择排序和堆排序;从其思想和编程来说:
1.简单选择排序:
思想:顾名思义,排序的时候肯定会做选择,那么来看到底是怎样的?
第一趟:从整个未排序数组中选择最小数,然后和数组的首位置交换,既放在数组的第一个位置;
第二趟:从数组的第二个位置找,选择最小的数放在第二个位置上;
第三趟:从数组的第三个位置找,选择最小的数放在第三个位置上;
.........
第n-1趟:从第n-1个位置找,选择最小的数放到n-1位置(n为数组长度);
代码:
#include<stdio.h>
void ElectSort(int *arr,int len)
{
int minindex;//变量用来记录最小数的下标
int tmp;
for(int i=0;i<len-1;i++)
{
minindex=i;
for(int j=i+1;j<len;j++)
{
if(arr[minindex]>arr[j])
{
minindex=j;
}
}
tmp=arr[minindex];
arr[minindex]=arr[i];
arr[i]=tmp;
}
}
int main()
{
int arr[]={12,5,48,99,23,2,36,15,1,52};
int len=sizeof(arr)/sizeof(arr[0]);
ElectSort(arr,len);
for(int i=0;i<len;i++)
{
printf("%d ",arr[i]);
}
printf("\n");
return 0;
}
2.堆排序:
思想准备:首先要了解两个概念;
大根堆:父节点的数大于子节点的数据。(用来做升序)
小根堆:父节点的书小于子节点的数据。(用来做降序)
思想:(本文以升序为例)
第一步:将要排序的数写成数的形式;如图:
第二步:进行堆调整,注意:在调整的过程中,每交换一个叶子节点都要保证该叶子节点作为父节点时的堆也是大根堆,否则要调整。第一趟调整完,如图:
第三步:将一号位置和13号位置进行交换,如图:
第四步:从1号位置进行堆调整;调整完之后如图:
第五步:调整完之后进行交换当前1号位置和12号位置,交换完之后如图:
第六步:以此类推,重复第四、五步;直至所有的数据都被交换;之后调整好的树如下图所示:
以上就是堆排序的详细过程啦!!接下来看看怎么让计算机知道堆排序^O^
代码:
#include<stdio.h>
void HeapAdjust(int *arr,int i,int len)//大跟堆实现函数。i:父子节点 ;len:堆中的有效长度
{
for(int j=2*i;j<=len;j*=2)//j:父子节点为i下的左叶子节点
{
if(j<len && arr[j]<arr[j+1])//根节点下有左子数,有右子树。
{
j++;//j负责记录子节点下大数的下标。
}
if(arr[j]<arr[i])
{
break;//本身就是大跟堆时跳出循环
}
arr[0]=arr[i];//由于arr[0]不存放有效数据,可以用来做交换时的临时变量
arr[i]=arr[j];
arr[j]=arr[0];
i=j;
}
}
void HeapSort(int *arr,int len)//堆排序函数
{
int tmp;
for(int i=len/2;i>0;i--)//从最后一个父子节点开始调整为大跟堆
{
HeapAdjust(arr,i,len);
}
for(int j=len;j>0;j--)//将堆的第一个数和最后一个数交换
{
tmp=arr[1];
arr[1]=arr[j];
arr[j]=tmp;
HeapAdjust(arr,1,j-1);
}
}
int main()
{
int arr[]={-1,546,326,56,4,8,23,623,1,2,6,10};
int lens=sizeof(arr)/sizeof(arr[0]);
HeapSort(arr,lens-1);
for(int i=0;i<lens;i++)
{
printf("%d ",arr[i]);
}
printf("\n");
return 0;
}
以上所有内容就是选择排序哦。