排序算法:本次主要是功能的实现,各种算法的优劣未作讨论
- 冒泡排序
- 选择排序
- 插入排序
- 快速排序
冒泡排序,每次将其中的元素,两两比较(是相邻的两个元素比较),如果前者大于后者,则交换其中数值,假设共有n个元素,外层循环只需要n-1次(两两比较嘛),由于每次循环将最大的值一直冒泡到最后面,所以我们下一次比较的结束位置可以前移,第一次我们将最大的值挪到最后面,第二次时,就可以不用管,以此类推。
c语言升序实现:
//冒泡排序
void bubble_sort(int *p,int l)
{
int i=0,j=0;
for(i=0;i<l-1;i++){//外循环控制循环次数
for(j=0;j<l-i-1;j++){//内循环两两比较大小
if(*(p+j+1)<*(p+j)){
int tem=*(p+j);//之后替换
*(p+j)=*(p+j+1);
*(p+j+1)=tem;
}
}
}
}
选择排序:
拿出一个元素和剩余的其他元素比较,也是需要两层循环,外层控制次数,内层比较大小。每次循环结果是将最小值放到最前面,在席次排序前,前面已经是有序数列,不需要再参加下一次循环。
C语言升序实现:
//选择排序
void select_sort(int *p,int l)
{
int i=0,j=0;
for(i=0;i<l-1;i++){//外循环控制循环次数
int pos=i;
for(j=i+1;j<l;j++){//内循环比较大小,如果满足条件,下标交换
if(*(p+pos)>*(p+j)){
pos=j;
}
}
if(pos!=i){//判断下标是否被交换,有则实际替换值
int tem=*(p+i);
*(p+i)=*(p+pos);
*(p+pos)=tem;
}
}
}
插入排序:
首先取第二位的值置为pos,判断他的前面是否有小于他的值,如果有,将其后移一位,一直判断到首位元素或者找不到更小的值时,就空出一个位置,将其pos的值赋给那个空的位置。
注意:在最后的pos填补的那个空缺的位置,由于在循环中,对j减完之后判断的不能进入循环内部,所以就是*(p+j+1)=pos。
C语言升序实现:
void resert_sort(int *p,int l)//插入排序
{
int i=0,j=0;
for(i=1;i<l;i++){//从第二个元素开始,
int pos=*(p+i);//值暂存再pos里面
for(j=i-1;j>=0 && pos>*(p+j);j--){//在j>=0的时候,查找比pos小的值,如果有,统一后挪一位
*(p+j+1)=*(p+j);
}
*(p+j+1)=pos;//pos补产生的空缺
}
}
快速排序:
优点在于快速,每次交替换三个值,冒泡选择排序新定义变量,而快速排序将数组中的三个元素进行交替,效率更高,
思想:
- 首先固定一个变量pos(位置为i),通常取首位,从右向左找比他小的值位置为J,找到后将其放到首位(i位),
- 然后从左向右查找比他大的值(新i位),放到刚才的位置(J位),新i位放pos值,i和J在同时向中间移动,边寻找边替换,直到i=j,一个组内替换完毕,
- 然后利用递归求他的前面的和后面的有序数列,直到递归的前后下标相等;
C语言代码实现:
void quick_sort(int *p,int left,int right)//快速排序
{
int pl=0,pr=0,pos=0;
if(left<right){//直到左下标大于等于右下标
pos=*(p+left);
pl=left;
pr=right;
while(pl<pr){
while(pl<pr && *(p+pr)>=pos){//从右向左查找比pos小的数
pr--;
}
if(pl<pr)//判断终止循环的条件是找到类更小值,还是下标到达界限
*(p+pl)=*(p+pr);//如果找到小值,替换
while(pl<pr && *(p+pl)<pos){//从左向右查找比pos大的数
pl++;
}
if(pl<pr)//判断循环终止条件
*(p+pr)=*(p+pl);//替换
}
*(p+pl)=pos;//填补原来的呢个坑
quick_sort(p,left,pl-1);//递归调用
quick_sort(p,pl+1,right);
}
}
这些都是最基础的排序,还有不同的变形,时间复杂度也未作讨论,不同的算法有不同的优缺点,主要看针对于什么样的数据,作者目前还是一个小小白,出错的地方希望大家指正,也希望自己在编程的路上保持一颗学习的心。