1、直接插入排序(straight insertion sort)是插入排序中最简单的排序算法,类似于玩纸牌时整理手中纸牌的过程。基本思想:依次将待排序序列中的每一个记录插入到一个已排好序的序列中,直到全部记录都排好序。取未排好序的数与排号的序列比较,进行插入。
#include<iostream>
using namespace std;
int main() {
int a[100] = { 0 };
int nm = 0;
int j = 0;
cin >> nm;
for (int i = 1; i <= nm; i++)
{
cin >> a[i];//输入排序的数,其中数组第一个数置空
}
for (int i = 2; i <= nm; i++)
{
a[0] = a[i];
for (j = i - 1; j > 0 && a[0] < a[j]; j--)
{
a[j + 1] = a[j];
}
a[j + 1] = a[0];
}
for (int i = 1; i < nm; i++)
cout << a[i] << ' ';
return 0;
}
2、希尔排序(shell sort)是对直接排序的一种改进,基本思想:先将整个待排序记录序列分割成若干个子序列,在子序列内分别进行直接插入排序,待整个序列基本有序时,再对全体记录进行一次直接插入排序。
(基本有序和局部有序不同,基本有序是指已接近正序,例如{1,2,8,4,5,6,7,3,9};局部有序只是某些部分有序,例如{6,7,8,9,1,2,3,4,5},局部有序不能提高直接插入排序算法的时间性能。)
设置增量gap。gap初始值设置为N/2。缩小方式一般为gap=gap/2. ,间隔相同的增量取一个数,取得的所有的数成一组。最后得到若干组,在进行直接插入排序。
3、冒泡排序
#include<iostream>
using namespace std;
int main() {
int a[100] = { 0 };
int nm = 0;
cin >> nm;
for (int i = 0; i < nm; i++)
{
cin >> a[i];
}
for (int i = 0; i < nm-1; i++)
for (int j = i + 1; j < nm; j++)
{
if (a[i] > a[j])
{
int t = a[i];
a[i] = a[j];
a[j] = t;
}
}
for (int i = 0; i < nm; i++)
cout << a[i] << " ";
return 0;
}
4、快速排序
快速排序(又称分区交换排序)是对起泡排序的一种改进,改进的着眼点是:在起泡排序中,记录的比较和移动是在相邻位置进行的,记录每次交换只能后移一个位置,因而总的比较次数和移动次数较多。在快速排序中,记录的比较和移动是从两端向中间进行的,关键码较大的记录一次就能从前面移动到后面,关键码较小的记录一次就能从后面移动到前面,记录移动的距离较远,从而减少了总的比较次数和移动次数。
基本思想:选取一个轴值,将待排序记录划分成独立的两部分,左侧记录的关键码均小于或等于轴值,右侧记录的关键码均大于或等于轴值,然后分别对这两部分重复上述过程,直到整个序列有序。
挖坑法:取数组第一个数a[0]作为基准,存到X,再从右往左找<X的数,假设是a[i],把他填到a[0]相当于把一个比较小的数放到了左边部分,此时右半部分a[i]成了一个坑,就从左边开始找>X的数(假设是a[j])填到a[i],此时左半部分a[j]成了一个坑,下一步就从右半部分找数据来填补,总的来说是回合制交换数据的感觉。
算法描述:
(1)i =L; j = R; 将基准数挖出形成第一个坑a[i]。
(2)j--由后向前找比它小的数,找到后挖出此数填前一个坑a[i]中。
(3)i++由前向后找比它大的数,找到后也挖出此数填到前一个坑a[j]中。
(4)再重复执行2,3二步,直到i==j,将基准数填入a[i]中。
5、堆排序