排序算法之时间复杂度O(n2)

排序算法是一个比较基础的问题,这里选择六个基础的排序算法进行介绍。从时间复杂度来进行介绍,其中选择排序,插入排序和冒泡排序的时间复杂度是 O ( n 2 ) O(n^2) O(n2)。堆排序,合并排序和快速排序的时间复杂度是 O ( n l o g 2 n ) O(nlog_{2}^{n}) O(nlog2n),这块内容会在下一个博客中介绍。
由于算法比较好理解,这里提供C++代码和简单的算法介绍。实力推荐一个手机APP动态展示算法,非常适合入门学习,上下班随时随地学习!
算法动态图解:链接:https://pan.baidu.com/s/1mX3s7VjLTKLr7MZhAQO-6Q
提取码:cv5y

选择排序

选择排序就是从重复“从待排序的序列数据中选出最小值”,将其与待排序序列的最左边的数字进行交换。在待排序的序列中选择出最小值采用的是线性查找。

void ChooseSort()
{
    
    
	int list[10] = {
    
     6,3,4,8,9,1,2,3,5,9 };
	int len = 10;
	int min_index = 0;
	int temp;
	for (size_t i = 0; i < len; i++)
	{
    
    
		min_index = i;
		for (size_t j = i; j < len-1; j++)
		{
    
    
			if (list[min_index] > list[j + 1])
			{
    
    
				min_index = j + 1;
			}
		}
		//将最小值放到最左侧
		temp = list[i];
		list[i] = list[min_index];
		list[min_index] = temp;
	}
	for (int i = 0; i <len; i++)
	{
    
    
		cout << list[i]<<",";
	}
	cout << endl;
}

因为选择排序中使用了线性查找来寻找最小值,因此在第一轮的时候需要比较n-1个数字。第二轮需要n-2个数字…到n-1时只需要比较1个数字。比较次数总共为(n-1)+(n-2)+…+1 ≈ \approx n 2 2 \frac{n^2}{2} 2n2,时间复杂度 O ( n 2 ) O(n^2) O(n2)

冒泡排序

顾名思义,如同算法的名称一样。我们每一轮都将该待排序的序列中最大的数字放到待排序数组的最右侧。从数组的左侧开始依次比较相邻的两个数字,如果左侧的数字比右侧大则进行交换。

void BubbleSort()
{
    
    
	int list[10] = {
    
     6,3,4,8,9,1,2,3,5,9 };
	int len = 10;
	int temp;
	for (size_t i = 0; i < len-1; i++)//n个元素需要比较n-1次(n-1趟)
	{
    
    
		//每一趟都会选择一个最大值放到数组右侧,已经排序好的不需要再检索
		for (size_t j = 0; j < len-i-1; j++)
		{
    
    
			if (list[j] > list[j + 1])
			{
    
    
				//交换
				temp = list[j];
				list[j] = list[j+1];
				list[j+1] = temp;
			}
		}
	}
	for (int i = 0; i < len; i++)
	{
    
    
		cout << list[i] << ",";
	}
	cout << endl;
}

每一轮都要进行一次线性比较,所以总的比较次数与选择排序一致。(n-1)+(n-2)+…+1 ≈ \approx n 2 2 \frac{n^2}{2} 2n2,时间复杂度 O ( n 2 ) O(n^2) O(n2)

插入排序

不断的从数组的未排序区域中取出元素,与左侧已归位的数字进行比较。若左侧数字更大,则进行交换。重复该操作,直到左边已归位的的数字比取出的数字更小,或者取出的数字已经移到整个序列的最左边为止。

  • 第一轮操作时,默认数组第一个元素已经排序完成。
void InsertSort()
{
    
    
	int list[10] = {
    
     6,3,4,8,9,1,2,3,5,9 };
	int len = 10;
	int temp;
	for (size_t i = 1; i < len; i++)
	{
    
    
		//将右侧待排序的第一个元素与左侧排序好的元素依次进行比较,限制j>0取到序列的最左侧
		for (size_t j = i; j > 0; j--)
		{
    
    
			if (list[j] < list[j - 1])
			{
    
    
				temp = list[j];
				list[j] = list[j - 1];
				list[j - 1] = temp;
			}
		}
	}
	for (int i = 0; i < len; i++)
	{
    
    
		cout << list[i] << ",";
	}
	cout << endl;
}

这里的时间复杂度按照最糟糕的情况计算,如果取出来的数字比左边已归位的数字都要小。那第2轮要比较1次,第3轮比较2次…最后一轮比较n-1次。所以总的比较次数为(n-1)+(n-2)+…+1 ≈ \approx n 2 2 \frac{n^2}{2} 2n2,时间复杂度 O ( n 2 ) O(n^2) O(n2)
附部分APP截图
ALT
在这里插入图片描述
不是推广APP,是真的很好用(笑哭)。APP链接有问题联系QQ:1678354579
以上代码全部手敲,经过完整测试无误;

猜你喜欢

转载自blog.csdn.net/weixin_42662358/article/details/99536001