简单排序算法之简单选择排序和直接插入排序

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/qq_26704711/article/details/79053141

简单选择排序简述:

简单选择排序(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),但直接插入排序的效率比简单选择排序和冒泡排序都要好一点。

没有更多推荐了,返回首页