经典排序算法学习

针对笔试面试过程中经典的几种排序算法做个记录。

1、归并算法

基本思想
  归并排序(merge sort)是利用归并的思想实现的排序方法,该算法采用经典的分治(divide-and-conquer)策略(分治法将题分(divide)成一些小的问题然后递归求解,而治(conquer)的阶段则将分的阶段得到的各结果合在一起,即分而治之)。以下为C++实现的归并排序算法。

class Solution{
public:
	vector<int> Mergesort(vector<int> num){
		vector<int> result(num);   // 原num直接复制一份到result数组,整个算法变成了非原址操作
		int size = result.size();
		mergesortcore(result, 0, size - 1);
		return result;
	}
	void mergesortcore(vector<int> &num, int left, int right){
		if (left < right){
			int middle = (left + right) / 2;
			mergesortcore(num, left, middle);
			mergesortcore(num, middle+1, right);
			merge(num, left, middle, right);
		}
	}

	void merge(vector<int> &num, int left, int middle, int right){ //将两个有序数组合并排序 
		int *temp = new int[right - left + 1];
		int i = left;
		int j = middle + 1;
		int t = 0; // 记录temp指针的索引
		while (i <= middle && j <= right)
		{
			if (num[i] < num[j]){
				temp[t++] = num[i++];
			}
			else{
				temp[t++] = num[j++];
			}
		}
		// 把左边剩余的数移入数组  
		while (i <= middle)
		{
			temp[t++] = num[i++];
		}
		// 把右边剩余的数移入数组
		while (j <= right)
		{
			temp[t++] = num[j++];
		}
		for (int i = 0; i < right - left + 1; i++)
		{
			num[i + left] = temp[i];
		}
		delete[] temp;
	}
};

以下为Python实现的归并排序算法。

class MergeSolution:
    def MergeSort(self,arr:list) -> list:
        if len(arr) <= 1:
            return arr
        mid = len(arr)//2
        a = self.MergeSort(arr[:mid])
        b = self.MergeSort(arr[mid:])
        return self.Merge(a,b)

    def Merge(self,a,b):
        i = j = 0
        res = []
        while i < len(a) and j < len(b):
            if a[i] <= b[j]:
                res.append(a[i])
                i += 1
            else:
                res.append(b[j])
                j += 1
        res.extend(a[i:])
        res.extend(b[j:])
        return res

归并排序算法分析

(1)稳定性
      归并排序是一种稳定的排序。
(2)存储结构要求
     可用顺序存储结构。也可以在链表上实现。
(3)时间复杂度
     时间复杂度无论是在最好情况下还是在最坏情况下均是O(nlgn)。
(4)空间复杂度
     需要一个辅助向量来暂存两有序子文件归并的结果,故其空间复杂度为O(n)

2、快速排序

基本思想:

1.先从向量中取出一个数作为轴点。

2.分区过程,将比这个轴点大的数全放到它的右边,小于或等于它的数全放到它的左边。

3.再对左右区间重复第二步,直到各区间只有一个数。

以下为C++实现的快速排序算法。

class Solution{
public:
	void Quicksort(vector<int> &numbers, int low, int high){
		int pivotpos;
		if (low < high){
			pivotpos = partition(numbers, low, high);
			Quicksort(numbers, low, pivotpos - 1);
			Quicksort(numbers, pivotpos + 1, high);
		}
	}
	int partition(vector<int> &numbers, int low, int high){
		int left = low, right = high;
		int pivot = numbers[left];  //这里选择了最左边的为pivot(轴点)
		while (left<right)
		{
			//顺序很重要,假如上面选择了最左边的为pivot,一定要先从右边开始找 
			while (pivot <= numbers[right] && left<right)  //从右到左找到一个小于pivot的数
				right--;
			while (pivot >= numbers[left] && left<right)  //从左到右找到一个大于pivot的数
				left++;
			swap(numbers[left], numbers[right]);

		}
		if (left == right)
			swap(numbers[left], numbers[low]);
		return left;
	}
};

以下为Python实现的快速排序算法。

class Solution:
    def Quicksort(self,arr:list,left:int,right:int):
        if left < right:
            privot_index = self.partition(arr,left,right)
            self.quicksort2_1(arr,left,privot_index-1)
            self.quicksort2_1(arr,privot_index+1,right)

    def partition(self,arr:list,left:int,right:int) -> int:
        privot = arr[left]
        head = left
        while left < right:
            while left < right and arr[right] > privot:
                right -= 1
            while left < right and arr[left] <= privot:
                left += 1
            arr[left],arr[right] = arr[right],arr[left]
        arr[head],arr[right] = arr[right],arr[head]
        return right

下面是利用Python语言强大的特性实现的简洁版快速排序算法。

class Solution:
    def quicksort(self,nums:list) -> list:
        if len(nums) <= 1:
            return nums
        greater = [x for x in nums[1:] if x > nums[0]]
        lesser = [x for x in nums[1:] if x <= nums[0]]
        return self.quicksort(lesser)+[nums[0]]+self.quicksort(greater)

快速排序算法分析

(1)稳定性
      快速排序是一种不稳定的排序。
(2)存储结构要求
     可用顺序存储结构。也可以在链表上实现。
(3)时间复杂度
     时间复杂度在最好情况下为O(n),平均情况是O(nlogn),最坏情况下是O(n^2)。
(4)空间复杂度
     快排实现了原址操作,故其空间复杂度为O(1)

 

最后放一张对常见排序算法的分析图。

  • 均按从小到大排列
  • k:代表数值中的 “数位” 个数
  • n:代表数据规模
  • m:代表数据的最大值减最小值

参考:
https://blog.csdn.net/qq_25827845/article/details/70994874
https://blog.csdn.net/doubleguy/article/details/81390951
https://wiki.jikexueyuan.com/project/easy-learn-algorithm/fast-sort.html
https://blog.csdn.net/MoreWindows/article/details/6684558
https://github.com/huihut/interview

 

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值