排序算法

这里把排序算法分为易、中、难三类:

易篇

1. 冒泡排序

冒泡排序
上图是一个逆向升序排列
理解: 有n个数据,划分为有序区无序区,比较两个数据大小,并根据排序方向交换称为一个冒泡过程,从起始位置完成多次冒泡获得一个最值称为一趟冒泡,每完成一趟冒泡有序区多一,完成 i 趟意味着有序区(不需要再次冒泡)数据量为 i 无序区数量为 n-i ,完成所有数据排序需要 n-1 趟,每趟需要冒泡 n - i - 1 次。且如果在某一趟没有发生交换则认为排序完成。时间复杂度O(n2)
C++代码如下:

//升序
void GululuSort(vector<int>& nums)
{
	int n = nums.size();
	for (int i = 0; i < (n - 1); i++) {      //一趟冒泡
		bool isExchange = false;
		for (int j = 0; j < (n - i - 1); j++)//一次冒泡
		{
			if (nums[j] > nums[j + 1])
			{
				swap(nums[j], nums[j + 1]);
				isExchange = true;
			}
		}
		cout << "第" << i + 1 << "次:";
		for (int i : nums)
		{
			cout << i << " ";
		}
		cout <<"isExchange="<< isExchange << endl;
		if (!isExchange)
			return;
	}
}

执行结果:
冒泡排序
优点: 对于只有少数混乱的数据,冒泡排序冒泡趟数少。
缺点: 每次冒泡都要进行数据交换,花费之间长。

2. 选择排序

理解: 其实选择排序和冒泡排序很像,区别就在于对数据的交换方式上,我们也将数据划分为有序区无序区,通过记录位置的方式将无序区的最值逐个放入有序区。n个数据完成排序需要选择n-1趟,每趟需要比较n-1-i次。时间复杂度O(n2)。
C++代码如下:

void SelectSort(vector<int>& nums)
{
	int n = nums.size();
	for (int i = 0; i < n-1; i++)			//一趟选择
	{
		int max_loc = n - i - 1;			//假设无序区最后一个值为最大值
		for (int j = 0; j < n - i - 1; j++)
		{
			if (nums[j] > nums[max_loc])
			{
				max_loc = j;				//比较记录一次
			}
		}
		swap(nums[max_loc], nums[n - i - 1]);//交换数据
		cout << "第" << i+1 << "趟" << " ";
		for (auto i : nums)
		{
			cout << i << " ";
		}
		cout << endl;
	}
}

执行结果:
选择排序
优点: 相对冒泡排序仅在每趟的最后交换数据,从这个角度上看选择排序是快于冒泡排序的。
缺点: 对于顺序已经排好的或者大多数数据位置都是有序的,依然需要选择同样的趟数。

3. 插入排序

理解: 把插入过程比作摸牌,假设第一个数据为手里面已有的牌,每次取一张牌和手里的牌对比,大于手里当前牌则将牌插入,否则手里将当前牌向后移动一个位置,然后与手里下一张比较,如此一直遍历完手里的牌将其插入。复杂度O(n2)

void InsertSort(vector<int>& nums)
{
	int n = nums.size();
	for (int i = 1; i < n; i++)				//一次摸牌
	{
		int tmp = nums[i];					//摸到的牌
		int j = i - 1;
		for (; j >= 0; j--)					//遍历手里牌
		{
			if (nums[j] < tmp)				//找到摸到牌在手里位置
			{
				break;
			}
			else
			{
				nums[j + 1] = nums[j];		//当前手里牌向后移动
			}
		}
		nums[j + 1] = tmp;					//插入摸到牌

		cout << "第" << i << "张" << " ";
		for (auto i : nums)
		{
			cout << i << " ";
		}
		cout << endl;
	}
}

优点: 如果输入数据是一个链表则不需要移动,仅插入即可。
缺点: 如果输入数据是一个数组需要移动数据。

中篇

难篇

总结

  1. 易篇中三种排序算法时间复杂度都为O(n2),针对不同的数据场景可对比选择。
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值