1.冒泡排序
冒泡排序是指数组中的数两两比较,满足条件的两个数进行排序操作,而非从第一位比较到最后一位;
C
#include<stdio.h>
int main()
{
int a[10]={5,6,8,2,4,1,9,3,7};//初始化一个乱序数组
for(int i=0;i<8;i++)
{
for(int j=0;j<9-i-1;j++)//每次比较a【i】之后数组种的数
{
if(a[j]>a[j+1])//如果a[j]>a[j+1] ,交换这两个位置上的数,使小的在前大的在后
{
int t=a[j];
a[j]=a[j+1];
a[j+1]=t;
}
}
}
for(int i=0;i<9;i++)//输出冒泡排序后的数组
printf("%d ",a[i]);
return 0;
}
冒泡排序的核心部分是双重嵌套循环,时间复杂度为O(N^2)
2.选择排序
选择排序是从第一个数开始,和数组之后的每一个数进行比较,找出最大的或最小的进行交换,交换完成后从下一个数开始再次进行比较,第一次比较n次,第二次比较n-1次,依次递减
C
#include<stdio.h>
int main()
{
int i = 0; //定义一个i并且赋初值为0,i作为数组的下标
int j = 0; //定义j并且赋初值为0,j作为找到最大值时所对应的下标
int k; //定义一个k,用来保存此次循环中最大值的下标
int temp; //定义一个中间变量temp,供以后交换值的时候使用
int a[]={4,2,5,6,8,1,7,9,3,0}; //定义了一个9个数的数组,并且初始化
int len = sizeof(a)/sizeof(a[0]); //len是数组的大小
for(i = 0;i<len;i++) //判断i是否小于len,执行下面的语句
{
k = i; //假设此次循环中的最大值就是当前的值
for(j = i+1;j<len;j++)
{
if(a[j]>a[k]) //将假设的当前最大值与后面的值比较
{
k = j; //若后面的值更大,则交换下标
}
}//当前最大值
if(k != i) //比较之后如果此次循环中最大值并非当前值
{
temp = a[i]; //将此次循环中的最大值与a[k]交换
a[i] = a[k];
a[k] = temp;
}
}
for(i=0;i<len;i++) //利用for循环将结果依次输出
{
printf("%d ",a[i]);
}
return 0;
}
C++
#include<iostream>
using namespace std;
int main()
{
int i = 0; //定义一个i并且赋初值为0,i作为数组的下标
int j = 0; //定义j并且赋初值为0,j作为找到最大值时所对应的下标
int k; //定义一个k,用来保存此次循环中最大值的下标
int temp; //定义一个中间变量temp,供以后交换值的时候使用
int a[]={4,2,5,6,8,1,7,9,3,0}; //定义了一个9个数的数组,并且初始化
//int len = sizeof(a)/sizeof(a[0]); //len是数组的大小
int len=a.size();
for(i = 0;i<len;i++) //判断i是否小于len,执行下面的语句
{
k = i; //假设此次循环中的最大值就是当前的值
for(j = i+1;j<len;j++)
{
if(a[j]>a[k]) //将假设的当前最大值与后面的值比较
{
k = j; //若后面的值更大,则交换下标
}
}//当前最大值
if(k != i) //比较之后如果此次循环中最大值并非当前值
{
temp = a[i]; //将此次循环中的最大值与a[k]交换
a[i] = a[k];
a[k] = temp;
}
}
for(i=0;i<len;i++) //利用for循环将结果依次输出
{
cout<<a[i]<<" ";
}
return 0;
}
3.直接插入排序
一个数组若是要按照从小到大的顺序排序,若第 i 项小于他的前一项或前几项,就将第 i 项插入所有比它大的数之前
#include<iostream>
using namespace std;
int main()
{
int i=0,j=0;
int k;
int temp;
int a[]={5,1,9,6,4,8,2,3,7,0};
int len=sizeof(a)/sizeof(a[1]);//数组长度
for(i=1;i<len;i++)
{
if(a[i-1]>a[i])//如果后项比前项小,将这一项插入比它大的数之前
{
temp=a[i];
for(j=i-1;j>=0&&a[j]>temp;j--)
{
a[j+1]=a[j];//将j以及之后的数向后移一位
}
a[j+1]=temp;//j+1是for循环机制哦,不懂的重开
}
}
for(i=0;i<len;i++)
cout<<a[i]<<" ";
return 0;
}
4.希尔排序
我们不难发现,以上三种排序的时间复杂度都为O(n^2)
而希尔排序的时间复杂度只有n*logn,所以希尔排序的效率要高出以上三种排序方法很多,
~~
希尔排序是特殊的插入排序,直接插入排序每次插入前的遍历步长为1,而希尔排序我们可以设置一个初始增量gap,每次排序gap/=2;我们就可以实现一个时间复杂度为n*logn的特殊的插入排序(希尔排序)
希尔排序是将待排序列分为若干个子序列,对这些子序列分别进行直接插入排序,当每个子序列长度为1时,再进行一次直接插入排序时,结果一定是有序的。常见的划分子序列的方法有:初始步长(两个子序列相应元素相差的距离)为要排的数的一半,之后每执行一次步长折半。
#include<iostream>
using namespace std;
int main()
{
int i=0,j=0;
int k;
int temp;
int a[]={5,1,9,6,4,8,2,3,7,0};
int len=sizeof(a)/sizeof(a[1]);//数组长度
int gap=len/2;//初始定义希尔排序的分段增量为数组的一半
while(gap)
{
for(i=0;i<len;i++)
{
for(j=i+gap;j<len;j+=gap)//增量为gap,每次比较i和i+gap项的值
{
if(a[i]>a[j])
{
temp=a[i];
a[i]=a[j];
a[j]=temp;
}
}
}
gap=gap/2;//结束时增量减少一半,进行下一次排序
}
for(i=0;i<len;i++)
cout<<a[i]<<" ";
return 0;
}