简单选择排序简述:
简单选择排序(Simple Selection Sort)可以说是冒泡排序的一种改版,它不再两两比较出较小数就进行交换,而是每次遍历比较当前数的后面所有数,最后再把最小的数和当前数进行交换。
排序前的准备:
#define MAXSIZE 10
//顺序表结构
template <class T>
struct SqList
{
T s[MAXSIZE + 1] = { NULL, 98, 24, 55, 81, 32, 77, 48, 60, 14, 8 }; //数组s,s[0]用作哨兵
int length = MAXSIZE; //s长度
void PrintArray();
};
typedef SqList<int> SList;
//交换l中的数组中下标为i和j的值
void Swap(SList *L, int i, int j)
{
int temp = L->s[i];
L->s[i] = L->s[j];
L->s[j] = temp;
}
template <class T>
void SqList<T>::PrintArray()
{
for (int i = 1; i <= MAXSIZE; i++)
{
cout << s[i] << " ";
}
cout << endl;
}
简单选择排序的实现:
//简单选择排序
//每次和后面所有的元素进行比较,选出最小的元素,进行交换。
void SelectSort(SList *L)
{
int i, j, min;
for (i = 1; i < L->length; i++)
{
min = i; //一开始默认最小元素下标的为自身下标
for (j = i + 1; j <= L->length; j++)
{
//遍历寻找最小元素
if (L->s[min] > L->s[j]) //如果存在比现在最小元素小的元素
{
min = j; //改变最小元素下标
}
}
//找到最小元素
if (i != min) //找到的元素不是原来的
{
Swap(L, i, min); //交换元素
}
}
}
简单选择排序的时间复杂度:
简单选择排序无论最好最坏情况都要比较的次数一样=1+2+3+...+(n-1)=(n(n-1))/2,即O(n^2)
但简单选择排序的交换的次数较少,所以相对冒泡排序效率更高。
直接插入排序简述:
直接插入排序(Straight Insertion Sort)换了一种思路,它把一个元素插入一个有序表的适当位置,从而得到一个新的长度加一的有序表。
直接插入排序实现:
//直接插入排序
//将一个新的元素插入一个有序表的适当位置,得到一个新的长度加一的有序表
void InsertSort(SList *L)
{
int i, j;
for (i = 2; i <= L->length; i++) //i从2开始,默认s[1]为一个有序表,s[0]作为哨兵位置
{
if (L->s[i] < L->s[i-1]) //如果要比较i比前一位小则进行插入,如果比前一位元素大则不进行插入
{
L->s[0] = L->s[i]; //把哨兵位置赋值为要插入的数
//将比哨兵大的元素都进行后移操作,来空出位置进行插入
for (j = i - 1; L->s[j] > L->s[0]; j--)
{
L->s[j + 1] = L->s[j];
}
//最后将空位赋值为要插入的数,即哨兵的值
L->s[j + 1] = L->s[0];
}
}
}
直接插入排序的时间复杂度:
最好情况:本身表就是有序的,每个后面的数和前面的进行一次比较,即时间复杂度为O(n);
最坏情况:表为逆序,所以要比较的次数=2+3+4+..+n=((n+2)(n-1)/2,即时间复杂度为O(n^2),
虽然时间复杂度都为O(n^2),但直接插入排序的效率比简单选择排序和冒泡排序都要好一点。