leetcode刷题 十大排序算法 C++实现(剑指offer5个)

本文详细介绍了十大经典排序算法的C++实现,包括快速排序、归并排序、堆排序等,并探讨了算法的复杂度和稳定性。此外,还通过实例解析了如何运用排序思想解决剑指Offer中的部分问题,如最小的k个数、数据流中的中位数等。
摘要由CSDN通过智能技术生成

目录

0 综述

0.1算法分类

0.2 算法复杂度

0.3 相关概念

1 常考排序

1.1快速排序(Quick Sort)

1.2 归并排序(Merge Sort)

1.3 堆排序(Heap Sort)

2 普通排序算法

2.1冒泡排序

2.2选择排序(Selection Sort)

2.3 插入排序(Insertion Sort)

3 其他排序

3.1 希尔排序(Shell Sort)

3.2 基数排序(Radix Sort)

3.3 计数排序(Counting Sort)

3.4 桶排序(Bucket Sort)

4 排序思想应用题剑指offer

剑指 Offer 40. 最小的k个数  堆

剑指 Offer 41. 数据流中的中位数 最小堆 最大堆

剑指 Offer 21. 调整数组顺序使奇数位于偶数前面 快排

剑指 Offer 45. 把数组排成最小的数 拼接 快排

剑指 Offer 51. 数组中的逆序对 归并排序 

0 综述

0.1算法分类

十种常见排序算法可以分为两大类:

  • 比较类排序:通过比较来决定元素间的相对次序,由于其时间复杂度不能突破O(nlogn),因此也称为非线性时间比较类排序。
  • 非比较类排序:不通过比较来决定元素间的相对次序,它可以突破基于比较排序的时间下界,以线性时间运行,因此也称为线性时间非比较类排序。 

0.2 算法复杂度

0.3 相关概念

  • 稳定:如果a原本在b前面,而a=b,排序之后a仍然在b的前面。
  • 不稳定:如果a原本在b的前面,而a=b,排序之后 a 可能会出现在 b 的后面。
  • 时间复杂度:对排序数据的总的操作次数。反映当n变化时,操作次数呈现什么规律。
  • 空间复杂度:是指算法在计算机内执行时所需存储空间的度量,它也是数据规模n的函数。 ‘

十大经典排序算法(动图演示)https://www.cnblogs.com/onepixel/p/7674659.html

常考排序

1.1快速排序(Quick Sort)

//快速排序
//双边循环法
int partion(int arr[],int low,int high)
{
	int startIndex=low;
	int pivot=arr[low];
	while(low<high)
	{
		while ((low<high) &&arr[high]>=pivot)
		{
			high--;
		}
		while((low<high) && arr[low]<=pivot)
		{
			low++;
		}

		if (low<high)
		{
			int tmp=arr[high];
			arr[high]=arr[low];
			arr[low]=tmp;
		}

	}

	arr[startIndex]=arr[low];
	arr[low]=pivot;
	return low;

	
}

//单边循环法
int partion(int arr[],int low,int high)
{
	int mark=low;
	int pivot=arr[low];

	for (int i=low;i<high;i++)
	{
		if (arr[i]<pivot)
		{	
			mark++;
			int tmp=arr[mark];
			arr[mark]=arr[i];
			arr[i]=tmp;
		}
	}
	

	arr[low]=arr[mark];
	arr[mark]=pivot;
	return mark;

	
}
void quickSort(int arr[],int low,int high)
{
	if (low<high)
	{
		int idx=partion(arr,low,high);
		quickSort(arr,low,idx-1);
		quickSort(arr,idx+1,high);
	}
}

1.2 归并排序(Merge Sort)

//归并排序
/*
使用分治思想:
假设两个子数组是有序的,将其按照有序序列合并,合并组成新的有序数组,再与其他部分合并
排序算法:归并排序【图解+代码】https://www.bilibili.com/video/BV1Pt4y197VZ?from=search&seid=7880178413492422518
*/
void merge(int arr[], int low, int mid, int high, int temp[])
{
    int i = low;         //左子数组开始位置
    int j = mid + 1;    //右子数组开始位置
    int t = 0;          //临时空间指针
    while (i <= mid && j <= high)
    {
        if (arr[i] < arr[j])
            temp[t++] = arr[i++];
        else
            temp[t++] = arr[j++];
    }
    //将左边剩余元素填充进temp中
    while (i <= mid)
        temp[t++] = arr[i++];
    //将右边子数组剩余部分填充到temp中
    while (j <= high)
        temp[t++] = arr[j++];
 
    //将融合后的数据拷贝到原来的数据对应的子空间中
    t = 0;
    while (low <= high)
    {
        arr[low++] = temp[t++];
    }
    
}
void MergeSort(int arr[], int low, int high, int temp[])
{
    if (low < high)             //只有low==high为一个元素的时候不用再细分自分组,融合
    {
        int mid = (low + high) / 2;
        //递归划分左半区
        MergeSort(arr, low, mid, temp);
        //递归划分右半区
        MergeSort(arr, mid + 1, high, temp);
        //合并已经排序的部分
        merge(arr, low, mid, high, temp);
    }
 
}

1.3 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值