数据结构各种排序:冒泡排序,快速排序,归并排序,插入排序,选择排序

参考文章
在这里插入图片描述
在这里插入图片描述

1.冒泡排序

1.1原理

参考文章

1.2时间复杂度和空间复杂度:

参考文章
时间复杂度:
这个时间复杂度还是很好计算的:外循环和内循环以及判断和交换元素的时间开销;
最优的情况也就是开始就已经排序好序了,那么就可以不用交换元素了,则时间花销为:[ n(n-1) ] / 2;所以最优的情况时间复杂度为:O( n^2 );
最差的情况也就是开始的时候元素是逆序的,那么每一次排序都要交换两个元素,则时间花销为:[ 3n(n-1) ] / 2;(其中比上面最优的情况所花的时间就是在于交换元素的三个步骤);所以最差的情况下时间复杂度为:O( n^2 );
综上所述:
最优的时间复杂度为:O( n^2 ) ;有的说 O(n),下面会分析这种情况;
最差的时间复杂度为:O( n^2 );
平均的时间复杂度为:O( n^2 );

空间复杂度:
空间复杂度就是在交换元素时那个临时变量所占的内存空间;
最优的空间复杂度就是开始元素顺序已经排好了,则空间复杂度为:0;
最差的空间复杂度就是开始元素逆序排序了,则空间复杂度为:O(n);
平均的空间复杂度为:O(1);

1.3python实现:

def bubble_sort(items):
    for i in range(len(items) - 1):
        for j in range(len(items) - 1 - i):
            if items[j] > items[j + 1]:
                items[j], items[j + 1] = items[j + 1], items[j]
    return items
 
 
list1 = [2,1,9,11,10,8,7]
print(bubble_sort(list1))

2.快速排序

2.1原理

参考文章
最差情况的快速排序退化成冒泡排序。

2.2python实现(递归):

def sub_sort(array, low, high):
    pivotkey = array[low]
    while low < high:
        while low < high and array[high] >= pivotkey:
            high -= 1
        array[low] = array[high]
        while low < high and array[low] <= pivotkey:
            low += 1
        array[high] = array[low]
    array[low] = pivotkey
    return low


def quick_sort(array, low, high):
    if low >= high:
        return
    if low < high:
        pivoloc = sub_sort(array, low, high)
        quick_sort(array, low, pivoloc - 1)
        quick_sort(array, pivoloc + 1, high)


if __name__ == "__main__":
    array = [49, 38, 65, 97, 76, 13, 27]
    print(array)
    quick_sort(array, 0, len(array) - 1)
    print(array)

3.归并排序

牺牲空间实现时间。对于单向链表,归并排序的复杂度较低。

3.1原理

参考文章

3.2复杂度

时间复杂度
在这里插入图片描述
这个图显然是二叉树的形式,所以若集合有n个元素,那高度就为log(n)

但其实在每一层做比较的时候,都是一个一个的向序列中放小的元素,每一层都是要放n次

所以时间复杂度为nlog(n)

3.3 python实现:

参考文章


def merge(s1,s2,s):
    """将两个列表是s1,s2按顺序融合为一个列表s,s为原列表"""
    # j和i就相当于两个指向的位置,i指s1,j指s2
    i = j = 0
    while i+j<len(s):
        # j==len(s2)时说明s2走完了,或者s1没走完并且s1中该位置是最小的
        if j==len(s2) or (i<len(s1) and s1[i]<s2[j]):
            s[i+j] = s1[i]
            i += 1
        else:
            s[i+j] = s2[j]
            j += 1

def merge_sort(s):
    """归并排序"""
    n = len(s)
    # 剩一个或没有直接返回,不用排序
    if n < 2:
        return
    # 拆分
    mid = n // 2
    s1 = s[0:mid]
    s2 = s[mid:n]
    # 子序列递归调用排序
    merge_sort(s1)
    merge_sort(s2)
    # 合并
    merge(s1,s2,s)


if __name__ == '__main__':
    s = [1,7,3,5,4]
    merge_sort(s)
    print(s)

4.插入排序

4.1原理

参考文章
插入排序原理很简单,将一组数据分成两组,我分别将其称为有序组与待插入组。每次从待插入组中取出一个元素,与有序组的元素进行比较,并找到合适的位置,将该元素插到有序组当中。就这样,每次插入一个元素,有序组增加,待插入组减少。直到待插入组元素个数为0。当然,插入过程中涉及到了元素的移动。

为了排序方便,我们一般将数据第一个元素视为有序组,其他均为待插入组。

下面以升序为例进行一次图解:
在这里插入图片描述

4.2复杂度

两层循环:n^2。
对于有的文章说n^2/2,算复杂度要去掉不重要成分,这里系数1/2就是不重要成分。

4.3python实现

参考文章

def insertSort(arr):
    length = len(arr)
    for i in range(1,length):
        x = arr[i]
        for j in range(i,-1,-1):
            # j为当前位置,试探j-1位置
            if x < arr[j-1]:
                arr[j] = arr[j-1]
            else:
                # 位置确定为j
                break
        arr[j] = x

arr = [4, 7 ,8 ,2 ,3 ,5]
insertSort(arr)
print(arr)

5.选择排序

5.1原理

参考文章

5.2复杂度

选择排序的时间复杂度为:O(n^2),空间复杂度:O(1)

选择排序是不稳定的;

5.3python实现

参考文章

def getmin(arr):
    min = arr[0];
    min_index = 0;
    for i in range(0,len(arr)):
        if arr[i]<min:
            min = arr[i]
            min_index = i
    return min_index

#SelectSort
def selectSort(arr):
    newArr = [];
    for i in range(0,len(arr)):
        min = getmin(arr);
        newArr.append(arr.pop(min))
    return newArr;

#test the output
a = [4,6,9,1,3,87,41,5]
print(selectSort(a))
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值