排序算法(一)

交换排序

  • 冒泡排序
    原理
    1. 比较相邻的元素。如果第一个比第二个大,就交换他们两个。
      2.对每一对相邻元素做同样的工作,从开始第一对到结尾的最后一对。在这一点,最后的元素应该会是最大的数。
    2. 针对所有的元素重复以上的步骤,除了最后一个。
    3. 持续每次对越来越少的元素重复上面的步骤,直到没有任何一对数字需要比较。
    代码
    # -*- coding:utf-8 -*-
    class Solution:
        def bubble_sort(self, list):
            for i in range(len(list)-1):
                for j in range(len(list)-1-i):
                    if list[j] > list[j+1]:
                        list[j], list[j+1] = list[j+1], list[j]
            return list
    
    特点
    • 冒泡排序总的平均时间复杂度为O(n2)

    • 冒泡排序就是把小的元素往前调或者把大的元素往后调。相邻的两个元素比较,交换也发生在这两个元素之间。所以,如果两个元素相等,是不会再交换的;如果两个相等的元素没有相邻,那么即使通过前面的两两交换把两个相邻起来,这时候也不会交换,所以相同元素的前后顺序并没有改变,所以冒泡排序是一种稳定排序算法。

  • 快速排序
    原理
    • 首先设定一个分界值,通过该分界值将数组分成左右两部分

    • 将大于或等于分界值的数据集中到数组右边,小于分界值的数据集中到数组的左边。此时,左边部分中各元素都小于或等于分界值,而右边部分中各元素都大于或等于分界值。

    • 然后,左边和右边的数据可以独立排序。对于左侧的数组数据,又可以取一个分界值,将该部分数据分成左右两部分,同样在左边放置较小值,右边放置较大值。右侧的数组数据也可以做类似处理。

    • 重复上述过程,可以看出,这是一个递归定义。通过递归将左侧部分排好序后,再递归排好右侧部分的顺序。当左、右两个部分各数据排序完成后,整个数组的排序也就完成了。

    代码
    # -*- coding:utf-8 -*-
    class Solution:
        def quick_sort(self, list):
            if len(list)<2:
                return list
            else:
                n = len(list)
                mid = list[n//2]
                left, right = [], []
                list.remove(mid)
                for i in range(n-1):
                    if list[i] <= mid:
                        left.append(list[i])
                    else:
                        right.append(list[i])
            return self.quick_sort(left) + [mid] + self.quick_sort(right)
    
    特点
    • 稳定性:快排是一种不稳定排序,比如基准值的前后都存在与基准值相同的元素,那么相同值就会被放在一边,这样就打乱了之前的相对顺序

    • 比较性:因为排序时元素之间需要比较,所以是比较排序

    • 时间复杂度:快排的时间复杂度为O(nlogn)

    • 空间复杂度:排序时需要另外申请空间,并且随着数列规模增大而增大,其复杂度为:O(nlogn)

    • 归并排序与快排 :归并排序与快排两种排序思想都是分而治之,但是它们分解和合并的策略不一样:归并是从中间直接将数列分成两个,而快排是比较后将小的放左边大的放右边,所以在合并的时候归并排序还是需要将两个数列重新再次排序,而快排则是直接合并不再需要排序,所以快排比归并排序更高效一些,可以从示意图中比较二者之间的区别。

    • 快速排序有一个缺点就是对于小规模的数据集性能不是很好

你可能感兴趣的:(排序算法(一))