【20221208】【排序专题】

一、冒泡排序(稳定排序)

思想:冒泡排序的思想就是比较当前数和后一个数的大小,将较大的数往后移动,这样可以确保一轮下来能将最大的数放在数组的最末端。然后重复此操作即可完成排序。

上面第一轮比较完,我们可以看到最大的数5已经被放在了最端,此时我们只需要将去掉最大的数的那部分(2,3,1,4)进行重复的操作。

 

class Solution {
public:
    vector<int> MySort(vector<int>& arr) {
        // 冒泡排序
        if(arr.size()==1)   return arr;
        for(int i=0;i<arr.size()-1;i++)
        {
            for(int j=0;j<arr.size()-1-i;j++)
            {
                if(arr[j]>arr[j+1]) swap(arr[j],arr[j+1]);
            }
        }
        return arr;
    }
};

如果数组一共有length个元素,则一共需要进行length-1轮比较,每轮完成后都会少一个进行比较。

若文件的初始状态是正序的,一趟扫描即可完成排序。所以,冒泡排序最好的时间复杂度为 O(n)

若初始文件是反序的,需要进行 n-1趟排序。每趟排序要进行 n-1 次关键字的比较(1≤i≤n-1),且每次比较都必须移动记录三次来达到交换记录位置,冒泡排序的最坏时间复杂度为O(n2)。

综上,因此冒泡排序总的平均时间复杂度为O(n2)


 二、快速排序

快速排序(Quick Sort):快速排序用到了分治思想,同样的还有归并排序。乍看起来快速排序和归并排序非常相似,都是将问题变小,先排序子串,最后合并。快速排序又是对冒泡排序的一种改进方法,在冒泡排序中,进行元素的比较和交换是在相邻元素之间进行的,元素每次交换只能移动一个位置,所以比较次数和移动次数较多,效率相对较低。而在快速排序中,元素的比较和交换是从两端向中间进行的,较大的元素一轮就能够交换到后面的位置,而较小的元素一轮就能交换到前面的位置,元素每次移动的距离较远,所以比较次数和移动次数较少,速度较快,故称为“快速排序”。

快速排序的基本思想是:

  1. 在待排序的元素任取一个元素作为基准(通常选第一个元素,但最优的选择方法是从待排序元素中随机选取一个作为基准),称为基准元素;
  2. 将待排序的元素进行分区,比基准元素大的元素放在它的右边,比其小的放在它的左边;
  3. 对左右两个分区重复以上步骤直到所有元素都是有序的。

 

 

void quickSort(vector<int>& nums, int left, int right) {

	if (left < right)
	{
		int base = nums[left];
		int low = left, high = right;
		while (low < high)
		{
			while (low < high && nums[high] >= base)
			{
				high--;
			}
			swap(nums[low], nums[high]);
			while (low < high && nums[low] <= base)
			{
				low++;
			}
			swap(nums[low], nums[high]);
		}
		quickSort(nums, left, low - 1);	
		quickSort(nums, low + 1, right);
	}
}

int main() {
	vector<int> nums = { 2,3,5,1,4 };
	for_each(nums.begin(), nums.end(), [=](int x) {cout << x << " "; });
	cout << endl;

	quickSort(nums, 0, nums.size() - 1);
	for_each(nums.begin(), nums.end(), [=](int x) {cout << x << " "; });
}

 

 

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值