刚开始学编程最让我感兴趣的就是算法,各种各样的算法,而刚开始接触算法的时候,接触到的就是排序算法,各种各样的排序算法,今天我就想基于小编个人的理解,写一写排序算法的思路
目录
在介绍排序之前先引入一个按照数组下标进行交换的算法
void swap(int a[max],int i,int j){
int temp;
temp=a[i];
a[i]=a[j];
a[j]=temp;
}
1.冒泡排序
基本思想:冒泡法也称做沉底法,每相邻俩个记录关键字比较大小,大的记录往下沉,每一遍把最后一个下沉的位置记下,下一遍只需要检查比较到此为止。
思想比较简单,但是怎么实现呢?
关键字的比较就是比较大小,每一遍的比较就是一层循环,每次比较完之后,下一次的重新比较就是再一次的循环,所以只需要俩层for循环就可搞定
void maopao(int a[max]){//1
int i;
int j;
for(i=0;i<max;i++){//外层控制每一次循环的终止范围
for(j=0;j<max-i-1;j++){//内层是逐个比较
if(a[j]>a[j+1]){//大的往后放,就是所谓的下沉
swap(a,j,j+1);
}
}
}
}
2.选择排序
基本思想:是从待排序的序列中选区一个关键字值最小的记录,把它和第一个位置交换存储位置,并且依次重复上述操作,直至有序。
分析思路:有比较就是需要进行一层循环,依次比较,找出最小值,每次的第一个存储位置都是不断的在变化,所以需要一个外层循环,控制所谓的“第一个存储位置”的改变。
void xuanze(int a[max]){//2
int i;
int j;
int minindex;
for(i=0;i<max;i++){//控制第一个存储位置的变化
minindex=i;//假设第一个存储位置就是最小的值
for(j=i+1;j<max;j++){//找出第一存储位后面的数的最小值
if(a[minindex]>a[j]){
minindex=j;
}
}
if(minindex!=i){//判断第一存储位上面的值是否还是最小的,不是就把它换成最小的
swap(a,minindex,i);
}
}
}
3.插入排序
基本思想:将一个记录插入到一个有序列表中,从而得到一个新的,记录数+1的有序列表
刚开始接触插入排序看到这个思想也很蒙蔽,本来待排序就是无序的,怎么就必须把一个记录处插到有序序列中呢?
这个就非常令人费解!
但是有没有想过一个问题,就是如果只有一个数字的时候,它属于有序还是无序呢?显然是属于有序的那么就出来了!
向一个数字里面加入后面一串数字中的最小值,那么插入的操作不就是(“将一个记录插入到一个有序列表中”)?
接下来再说一个问题,怎么插?
还是比较数值大小并且交换位置来实现插入操作!
具体代码如下:
void charru(int a[max]){//3
int i;
int j;
for(i=0;i<max;i++){
for(j=0;j<i;j++){
if(a[i]<a[j]){//插入操作就是比较+交换
swap(a,i,j);
}
}
}
}
每次交换都把有序数组里面最大的数字往后移一位!
希尔排序:
个人理解的基本思想:就是把它当成插入排序的一个特殊版本,本质上还是插入排序,但是效率在某些情况下是比插入排序高的,因为最终一次排序就是一个简单的插入排序,但是最后一次插入之前,排序就已经快要排好了,最终把它排好时间是比直接简单插入排序快的
代码如下:
void xier(int a[max]){//4
int gre=max/2;//增量
int i;
int j;
while(gre>0){
for(i=0;i<max;i+=gre){//直接插入排序算法
for(j=0;j<i;j+=gre){
if(a[i]<a[j]){
swap(a,i,j);
}
}
}
gre/=2;//每次一次缩减
}
}
注意:增量的缩减是关键,初始就是待排序数组长度/2,之后每次都/2;
喜欢记得点个关注哟!
接下来还会有更多自己的一些感想与大家分享!