排序算法
1、冒泡排序:
冒泡排序就像它名字一样,冒泡,就像水里的气泡一样往上冒,通过多次冒泡,可以把小的往前,也可把大的往后,使得一组数据大小有序排列,举个例子:
待排 :4 3 2 5 1
- 3 2 4 1 5
- 2 3 1 4 5
- 2 1 3 4 5
- 1 2 3 4 5
#include<stdio.h>
void sort(int a[],int n)//冒泡
{
int i,j;
for(i=0;i<n;i++) //此循环执行n次,依次将最大数,次大数······放到后面,从而实现从小到大排序
{
for(j=0;j<n-i-1;j++) //此循环将较大的数放到后面,大数就像冒泡一样往后冒
{
if(a[j]>a[j+1])
{
int temp=a[j];
a[j]=a[j+1];
a[j+1]=temp;
}
}
}
}
int main()
{
int n,i;
scanf("%d",&n);
int a[n];
for(i=0;i<n;i++)
{
scanf("%d",&a[i]);
}
sort(a,n);
for(i=0;i<n;i++)
{
printf("%d ",a[i]);
}
return 0;
}
测试
2、选择排序:
选择排序是每次通过循环比较后,记下最大或者最小数的位置,然后交换。举个例子:
4 3 2 5 1(记下最小数位置)
- 1 3 2 5 4 1最小,1和4交换
- 1 2 3 5 4 在后四个数中2最小,2和3交换
- 1 2 3 5 4 在后三个数中3最小,位置不变
- 1 2 3 4 5 在后两个数中4最小,4和5交换
代码:
#include<stdio.h>
void SelSort(int a[],int n)//选择
{
int i,j;
for(i=0;i<n-1;i++)
{
int minIndex=i;
for(j=i+1;j<n;j++)
{
if(a[minIndex]>a[j])
{
minIndex=j;
}
}
int temp=a[i];
a[i]=a[minIndex];
a[minIndex]=temp;
}
}
int main()
{
int n,i;
scanf("%d",&n);
int a[n];
for(i=0;i<n;i++)
{
scanf("%d",&a[i]);
}
SelSort(a,n);
for(i=0;i<n;i++)
{
printf("%d ",a[i]);
}
return 0;
}
测试
3、插入排序:
插入排序,就像咱们斗地主一样,把大的放一边,小的放一边,摸起一张牌后,要找到适合它的位置插入。举个例子:
4 3 2 5 1
- 4 3 2 5 1 只有4,位置不变
- 3 4 2 5 1 3比4小,插到四前面
- 2 3 4 5 1 2比3、4小,插到最前面
- 2 3 4 5 1 5比前面的数都大,不变
- 1 2 3 4 5 1最小,插到最前面
注意:这里的插入是通过一个数一个数的移动完成的
代码:
#include<stdio.h>
void InsertSort(int a[],int n)//插入
{
int i,j;
for(i=1;i<n;i++)
{
for(j=i-1;j>=0&&a[j]>a[j+1];j--)//寻找合适的插入位置,通过一个数一个数的移动完成的
{
int temp=a[j];
a[j]=a[j+1];
a[j+1]=temp;
}
}
}
int main()
{
int n,i;
scanf("%d",&n);
int a[n];
for(i=0;i<n;i++)
{
scanf("%d",&a[i]);
}
InsertSort(a,n);
for(i=0;i<n;i++)
{
printf("%d ",a[i]);
}
return 0;
}
测试:
4、归并排序:
归并排序涉及到递归(不懂得小伙伴自己去查查,自己调自己了)
需要开辟一个辅助数组来存数据;
每次归并一部分,慢慢扩大范围,使得整组数据有序。还是举个例子:
4 3 2 5 1
- 被划分为 4 3 2 、5 1两部分
- 再划分 4 3 、 2 、 5、 1四部分
- 4 3再划分为 4 、3两部分 (实际上并不是这样,只是为了方便理解,实际是先把左边划分归并完后,再来划分归并右边的) 接下来开始归并
- 4 和 3归并 3小变成 3 4
- 3 4和2归并 2小变成 2 3 4
- 5和1 归并 变成 1 5
- 2 3 4和 1 5归并谁小谁放前面
- 1 2 3 4 5完成
这个理解起来稍微复杂一点,但是他的时间复杂度比前三个都小。
代码:
#include<stdio.h>
void MergeSort(int a[],int L,int R)//归并排序
{
if(L==R)return;
int mid=(L+R)/2;
MergeSort(a,L,mid); //对半分,先使得左边有序,
MergeSort(a,mid+1,R); //再使得右边有序,最后使得整体有序
int temp[R-L+1]; //开一个辅助数组
int i=0;
int p1=L,p2=mid+1;
while(p1<=mid&&p2<=R) //归并过程
{
temp[i++]=a[p1]<a[p2]?a[p1++]:a[p2++]; //谁小把谁放进辅助数组
}
while(p1<=mid) //接下来这两个循环是把没归并完的数放入辅助数组
{
temp[i++]=a[p1++];
}
while(p2<=R)
{
temp[i++]=a[p2++];
}
for(i=0;i<=R-L;i++) //把辅助数组的值复制给原数组
{
a[L+i]=temp[i];
//printf("%d ",temp[i]); 此处可打印观看归并过程
}
//printf("\n");
}
int main()
{
int n,i;
scanf("%d",&n);
int a[n];
for(i=0;i<n;i++)
{
scanf("%d",&a[i]);
}
MergeSort(a,0,n-1);
for(i=0;i<n;i++)
{
printf("%d ",a[i]);
}
return 0;
}