四种基本排序总结(C++)
一、选择排序
思路:现将一组数输入数组,从第一个数开始比较,与其后面的每一个数进行比较,若后面的数字比位于第一个位置的数字小的话,两个数字进行交换,当第一个位置的数字与它后面的所有数字比较(交换)过后,第一个位置上的数字就是最小的数字。再从第二个数字比较,同理再经过一遍比较后,第二位的数字是第二小的数字…以此类推,最后在这个数组中已经从小到大排好了顺序,再将此数组依次输出即可。
难点:比较的顺序的内在逻辑关系(嵌套循环中两个变量的关系)
代码:
#include<iostream>
using namespace std;
int main()
{
int n,k,x=1;
cin>>n;
int a[n+1];
a[0]=1000000; //a[0]表示存储每次比较后小的那个数
for(int i=1;i<=n;i++)
cin>>a[i];
for(int i=1;i<=n;i++)
{
for(int j=i;j<=n;j++)
{
if(a[j]<a[0])
{
a[0]=a[j]; //更新小的数
k=j;
}
}
a[k]=a[i];
a[i]=a[0];
a[0]=1000000; //保证下一次循环时第一个数比a[0]小
}
for(int i=1;i<=n;i++)
cout<<a[i]<<" ";
return 0;
}
————————————————————————————————————————————————————————
二、冒泡排序
思路:先将数字输入数组中,从第一个数字开始与其后面一位比较,若后面一位比它小,则两数字交换位置,12比23比34比45比…一轮过后最后一个便是最大的数字,再来一轮,比较的次数要比上一轮少一次(已确定了最后一位)此时可以确定第二大的一个数在倒数第二个位置上…以此类推,最后在这个数组中已经从小到大排好了顺序,再将此数组依次输出即可。
难点:涉及的多次数据交换
代码:
#include<iostream>
using namespace std;
int main()
{
int n;
cin>>n;
int a[n+1];
for(int i=1;i<=n;i++)
{
cin>>a[i];
}
for(int i=1;i<=n-1;i++)
{
for(int j=1;j<=n-i;j++)
{
if(a[j]>a[j+1])
{
a[0]=a[j+1]; //a[0]起到中间量的作用
a[j+1]=a[j];
a[j]=a[0]; //交换位置
}
}
}
for(int i=1;i<=n;i++)
{
cout<<a[i]<<" ";
}
return 0;
}
————————————————————————————————————————————————————————
三、插入排序
思路:现将数字输入一个数组中,从第二个数字开始,比较它和它前面的所有数字,当它前面有一位数比它小,则将它移到该数后面一个位置(利用“中间量”和“部分数组向后平移”实现)当最后一个位置的上的数比较(交换)完成后,数组中已经从小到大排好了顺序,再将此数组依次输出即可。
难点:查找位置过程以及转换位置的过程中数组下标之间的关系
代码:
#include<iostream>
using namespace std;
int main()
{
int n,j,tmp;
cin>>n;
int a[n+1];
for(int i=1;i<=n;i++)
{
cin>>a[i];
}
for(int i=2;i<=n;i++)
{
tmp=a[i]; //取出这个数便于后面数组平移
for(j=i-1;j>=1;j--)
{
if(a[j]<tmp) //找到应该插入的位置(下标数)
break;
}
for(int k=i;k>=j+1;k--)
{
a[k]=a[k-1]; //向后平移数组为插入让开空间
}
a[j+1]=tmp; //插入该数
}
for(int i=1;i<=n;i++)
{
cout<<a[i]<<" ";
}
return 0;
}
————————————————————————————————————————————————————————
四、桶排序
思路:在一定整数范围内定义一个数组初始化为0,每输入一个数,则在下标为这个数的数组中标记一下(可以输入一个数),最后按下标从小到大遍历整个数组,输出数组中不为0的数组的下标,输出的下标便是从小到大排好顺序的那一组数。
难点:巧用下标和标记
代码:
#include<iostream>
#include<cstring>
using namespace std;
int main()
{
int n,k;
cin>>n;
int a[100001]={0}; //初始数组为0,配合后面做标记
//memset(a,0,sizeof(a));
for(int i=1;i<=n;i++)
{
cin>>k;
a[k]++; //使该数对应的数组中的值加一(做标记)
}
for(int i=1;i<=100001;i++)
{
if(a[i]!=0)
{
cout<<i<<" "; //输出做过标记的数组的下标
}
}
return 0;
}