常见的排序算法
*排序算法有很多,所以在特定情景中使用哪一种算法很重要。为了选择合适的算法,可以 按照建议的
顺序考虑以下标准:①执行时间 ②存储空间 ③编程工作
对于数据量较小的情形,程序执行时间和所需存储空间差别不大,主要考虑编程工作的方便与否;而
对于数据量大的待排序数据来说执行时间尤为首要。*
常见常用的排序法有:
一、冒泡排序
二、选择排序
三、归并排序
四、插入排序
五、快速排序
*下面将这几种常见的排序算法分享给大家,有疑问的同学可以加群(QQ群:952463167)
咨询。由于个人知识能力有限,难免出现出现错误,若有错误之处还应大家指教。*
一、冒泡排序
- 冒泡排序算法的原理如下:
1.比较相邻的元素。如果第一个比第二个大,就交换他们两个。
2.对每一对相邻元素做同样的工作,从开始第一对到结尾的最后一对。在 这一 点,最后的元素应该会是最大的数。
3.针对所有的元素重复以上的步骤,除了最后一个。
4.持续每次对越来越少的元素重复上面的步骤,直到没有任何一对数字需要比较。*
//具体代码如下
#include<stdio.h>
void main()
{
int array[10];
int i,j,k;
printf("输入array;\n");
for(i=0;i<10;i++) scanf("%d",&array[i]);
for(i=0;i<10-1;i++)
for(j=0;j<10-i-1;j++)
if(array[j+1]<array[j])
{
k=array[j+1];
array[j+1]=array[j];
array[j]=k;
}
for(i=0;i<10;i++) printf("%5d",array[i]);
}
//冒泡排序效率 O(n²),因此只适用于排序小的列表
二、选择排序
- 选择法排序算法的原理如下:
1.第1趟,在待排序记录r[1]r[n]中选出最小的记录,将它与r[1]交换;
2.第2趟,在待排序记录r[2]r[n]中选出最小的记录,将它与r[2]交换;
3.以此类推,第i趟在待排序记录r[i]~r[n]中选出最小的记录,将它与r[i]交换,使有序序列不断增长直到全部排序完毕。**
//简单选择法排序
#include<stdio.h>
#define N 6
void main()
{
int i,j,t;
int array[N];
printf("请输入%d个数:",N);
for(i=0;i<N;i++) scanf("%d",&array[i]);
for(i=0;i<N-1;i++)
for(j=1+i;j<N-1;j++)
if(array[i]>array[j])
{
t=array[j];
array[j]=array[i];
array[i]=t;
}
for(i=0;i<N;i++)
printf("%d ",array[i]);
}
//简单选择法排序
#include<stdio.h>
#define N 6
main()
{
int i,j,k,t;
int array[N];
printf("请输入%d个数:",N);
for(i=0;i<N;i++) scanf("%d",&array[i]);
for(i=0;i<N-1;i++)
{
k=i;
for(j=1+i;j<N;j++)
if(array[k]>array[j]) k=j;
if(k!=i)
{
t=array[k];
array[k]=array[i];
array[i]=t;
}
}
for(i=0;i<N;i++)
printf("%d ",array[i]);
}
//选择法排序效率O(n²),因此也适用于排序小的列表
三、归并排序
- 归并法排序算法的原理如下:
1.申请空间,使其大小为两个已经排序序列之和,该空间用来存放合并后 的序列
2.设定两个指针,最初位置分别为两个已经排序序列的起始位置
3.比较两个指针所指向的元素,选择相对小的元素放入到合并空间,并移动指针到下一位置
4.重复步骤3直到某一指针超出序列尾
5.将另一序列剩下的所有元素直接复制到合并序列尾
//归并排序模板
#include<stdio.h>
#define M 10
#define N 10
void main()
{
int a[M]={ … … }; //一开始就有顺序
int b[N]={ … … }; //一开始就有顺序
int c[M+N];
int i=0, j=0, k=0; // i:a的下标,j:b的下标,k:c的下标
while(i<M&&j<N ) //只要a,b均有未取元素
if(a[i]<b[j]) c[k++]=a[i++];
else c[k++]=b[j++];
while(i<M) c[k++]=a[i++];
while(j<N) c[k++]=b[j++];
for(i=0;i<M+N;i++) printf("%5d",c[i]);
}
//效率O(nlogn),归并的最佳、平均和最糟用例效率之间没有差异。 适用于排序大列表基于分治法。
//PS:分治算法将在第三期给大家分享,有兴趣的同学可以加QQ群:952463167,或关注我的博客
//利用归并排序排列两个字符串
#include<stdio.h>
void And(char str1[],char str2[],char str3[]);
void main()
{
char str1[30];
char str2[30];
char str3[60];
printf("请输入第一个有序字符串:");
gets(str1);
printf("请输入第er个有序字符串:");
gets(str2);
And(str1,str2,str3);
printf("%s",str3);
}
void And(char str1[],char str2[],char str3[])
{
int i=0,j=0,k=0;
while(str1[i]&&str2[j])
{
if(str1[i]<str2[j]) str3[k++]=str1[i++];
else str3[k++]=str2[j++];
}
while(str1[i]) str3[k++]=str1[i++];
while(str2[j]) str3[k++]=str2[j++];
str3[k]='\0';
}
//最佳效率O(n);最糟效率O(n²)与冒泡、选择相同,适用于排序小列表
//若列表基本有序,则插入排序比冒泡、选择更有效率。
四、插入排序
- 插入排序具体算法描述如下:
1.从第一个元素开始,该元素可以认为已经被排序
2.取出下一个元素,在已经排序的元素序列中从后向前扫描
3.如果该元素(已排序)大于新元素,将该元素移到下一位置
4.重复步骤3,直到找到已排序的元素小于或者等于新元素的位置
5.将新元素插入到下一位置中
6.重复步骤2~5
void InsertSort()
{
int i;
int j;
int temp
for(i=1;i<n;i++)//循环从第二个数组元素开始,因为arr[0]作为最初已排序部分
{
itemp=arr[i];//temp标记为未排序第一个元素
j=i-1;
while (j>=0&&arr[j]>temp)/*将temp与已排序元素从小到大比较,寻找temp应插入的位置*/
{
arr[j+1]=arr[j];
j--;
}
arr[j+1]=temp;
}
}
五、快速排序
- 快速排序的算法思想:
1.选定一个枢纽元素,对待排序序列进行分割
2.对分割之后的序列一个部分小于枢纽元素,一个部分大于枢纽元素
3.再对这两个分割好的子序列进行上述的过程。
PS:
a)由于快速排序算法比较难理解,有兴趣的同学可以关注我,下期快速排序法进行详细的讲解
b)快速排序涉及了递归排序算法,有兴趣的同学可以关注我,我将在第三期给大家具体介绍简单的入门算法,希望大家来捧场
#include<stdio.h>
#define N 10
void quick_sort(int left,int right);
int a[N];
void main()
{
int i;
printf("请输入%d个元素:",N);
for(i=0;i<N;i++) scanf("%d",&a[i]);
quick_sort(0,N-1);
for(i=0;i<N;i++) printf("%5d",a[i]);
}
void quick_sort(int left,int right)
{
int i,j,t,temp;
if(left>right) return;
temp=a[left];
i=left;
j=right;
while(i!=j)
{
while(a[j]>=temp&&i<j) j--;
while(a[i]<=temp&&i<j) i++;
if(i<j) {t=a[i];a[i]=a[j];a[j]=t;}
}
a[left]=a[i];
a[i]=temp;
quick_sort(left,i-1);
quick_sort(i+1,right);
}
//平均效率O(nlogn),适用于排序大列表。
/*此算法的总时间取决于枢纽值的位置;选择第一个元素作为枢纽,可能导致O(n²)的最糟用例效率。若数基本有序,效率反而最差。选项中间值作为枢纽,效率是O(nlogn)。
基于分治法。
PS:分治算法将在第三期给大家分享,有兴趣的同学可以加QQ群:952463167,或关注我的博客*/
快速排序算法详解:https://blog.csdn.net/weixin_44040023/article/details/103621216
有需要的同学可以关注我哟,下期将给大家分享快排的具体实现原理和给大家介绍常用的解决问题的使用算法。由于个人知识能力有限,难免出现出现错误,若有错误之处还应大家指教。我们的群号是:QQ群:952463167