十大排序算法简洁实现 C++

记录下十大排序算法的内核及改进。
不稳定排序:快选择谢尔顿。(快速、选择、希尔、堆)
算法分类:

时间复杂度:

图片转自:https://www.cnblogs.com/onepixel/articles/7674659.html
快排的空间复杂度为O(log2n)

在这里插入图片描述

一、比较排序

1. 交换排序

(一)冒泡排序

for(int i = 0; i < len - 1; i++)
{
	for(int j = 0; j < len - i - 1; j++)
	{
		if(arr[j] > arr[j + 1]) swap(arr[j], arr[j + 1]);
	}
}

(二)快速排序

简单版,但如果最左边的元素是最大值或最小值就会是最坏时间复杂度。

//一开始left = 0, right = len - 1;
void quickSort(int q[], int left, int right) 
{
	if (left >= right) return;
	int l = left - 1, r = right + 1, temp = q[left + right >> 1];
	while (l < r) 
	{
		while (q[++l] < temp);
		while (q[--r] > temp);
		if (l < r) swap(q[l], q[r]);
	}
	quickSort(q, left, r), quickSort(q, r + 1, right);
}

改进
//三值取中法


```cpp
int main()//测试
{
	vector<int> arr = {5, 3, 6, 7, 2, 1};
	quickSort(arr, 0, arr.size() - 1);
	
	for(int i = 0; i < arr.size(); i++)
	cout<<arr[i]<<" ";
	return 0;
}

第k大数 lc215
https://leetcode.cn/problems/kth-largest-element-in-an-array/

class Solution {
    public int findKthLargest(int[] nums, int k) {
        int n = nums.length;
        return qS(0, n - 1, nums, n - k);
    }

    public int qS(int left, int right, int[] nums, int k) {
        if (left >= right)
            return nums[k];
        int l = left - 1, r = right + 1, tmp = nums[(left + right) / 2];
        while (l < r) {
            while (nums[++l] < tmp);
            while (nums[--r] > tmp);
            if (l < r) {
                int a = nums[l];
                nums[l] = nums[r];
                nums[r] = a;
            }   
        }

        if (r >= k)
            return qS(left, r, nums, k);
        return qS(r + 1, right, nums, k);
    }
}
class Solution:
    def findKthLargest(self, nums: List[int], k: int) -> int:
        def quickSort(left, right, k):
            # 终止
            if left >= right:
                return nums[k]
            l, r = left - 1, right + 1
            mid = (left + right) // 2
            x = nums[mid]
            while l < r:
                r -= 1
                while nums[r] > x:
                    r -= 1

                l += 1
                while nums[l] < x:
                    l += 1
                
                if l < r:
                    nums[l], nums[r] = nums[r], nums[l]
            if r >= k:
                return quickSort(left, r, k)
            return quickSort(r + 1, right, k)
            
        n = len(nums)
        return quickSort(0, n - 1, n - k)

2. 插入排序

(一)插入排序

第一种:

int j, k;
for (int i = 1; i < len; i++)
      {
          j = i - 1;
          k = arr[i];
          while (j > -1 && k < arr[j] )
          {
              arr[j + 1] = arr[j];//比k大就往后移
              j--;
          }
          arr[j + 1] = k;//把k填进去
      }

第二种:

for(int i = 0; i < len; i++)
{
	for(int j = i; j > 0; j--)
	{
		if(arr[j - 1] > arr[j]) swap(arr[j - 1], arr[j]);
	}
}

(二)希尔排序

当d = 1时,最后一次排序可以视为插入排序。

	int i, j, d, temp, n = arr.size();
    d = n / 2;//设置增量
    
    while (d > 0)//边界条件
    {
        for (i = d; i < n; i++)//对所有组采用直接插入排序
        {
            temp = arr[i];//对相隔d个为止一组采用直接插入排序
            j = i - d;
            while (j > -1 && temp < arr[j])
            {
                arr[j + d] = arr[j];
                j = j - d;
            }
            arr[j + d] = temp;
        }
        d = d / 2;//减小增量
    }

参考:https://www.jianshu.com/p/502153724b91

3. 选择排序

(一)简单选择排序

for(int i = 0; i < len - 1; i++)
{
	for(int j = i + 1; j < len; j++)
	{
		if(arr[i] > arr[j]) swap(arr[i], arr[j]);
	}
}

(二)堆排序

void heapAdjust(vector<int>& arr, int k, int end)
{	
	for(int i = 2 * k + 1; i <= end; i = i * 2 + 1)
	{
		if (i < end && arr[i] < arr[i + 1]) i++;
		if (arr[k] > arr[i]) break;
		else
		{
			swap(arr[k], arr[i]);
			k = i;
		}
	}
}

void heapSort(vector<int> &arr, int len)
{
	int i;
	for (i = len / 2 - 1; i >= 0; i--) heapAdjust(arr, i, len - 1);
	for (i = len - 1; i > 0; i--)
	{
		swap(arr[0], arr[i]);
		heapAdjust(arr, 0, i - 1);
	}
}

4. 归并排序

(一)二路归并排序

觉得太复杂的话应先从mergeSort函数看起,然后再看merge函数。

void merge(int left, int mid, int right, vector<int> &arr)
{
	if(left >= right) return;
	int n = right - left + 1;
	int *temp = new int[n];//建立临时数组
	int l = left, r = mid + 1, index = 0;
	
	while(l <= mid && r <= right)
	temp[index++] = arr[l] <= arr[r] ? arr[l++] : arr[r++];
	while(l <= mid)
	temp[index++] = arr[l++];
	while(r <= right)
	temp[index++] = arr[r++];
	
	for(int i = 0; i < n; i++)//返回排序好的数组
	{
		arr[left + i] = temp[i];
	}
	
	delete []temp;
}

void mergeSort(int left, int right, vector<int> &arr)
{
	if(left > right)//判断是否为合法输入
	{
		cout<<"非法输入,请检查输入的参数!"<<endl;
		return;
	} 
	else if(left == right) return;
	
	int mid = (left + right) / 2;//找中点
	
	mergeSort(left, mid, arr);//开始分组递归
	mergeSort(mid + 1, right, arr);
	
	merge(left, mid, right, arr);//排序
}
int main()//测试
{
	vector<int> arr = {5, 3, 6, 7, 2, 1};
	mergeSort(0, arr.size() - 1, arr);
	for(int i = 0; i < arr.size(); i++)
	cout<<arr[i]<<" ";
	return 0;
}

(二)多路归并排序

二、非比较排序

1. 计数排序

2. 桶排序

3. 基数排序

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

zhanjuex

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值