常见排序算法的python实现(二)

       离上次更新blog过去四个月了, 感觉写blog跟写日记差不多,是需要耐心和坚持的。

       这次更新两个排序算法,一个是面试官最爱考的快排,一个是比较简单的归并排序。

一,快速排序:

首先贴代码:

"""快速排序"""
def quick_sort(list):
    len_of_list = len(list)
    if len_of_list <= 1:
        return list
    else:
        left_list = []
        right_list = []
        random_index = random.randint(len_of_list)
        value_temp = list[random_index]
        for i in range(len_of_list):
            if i != random_index:
                if list[i] <= value_temp:
                    left_list.append(list[i])
                else:
                    right_list.append(list[i])
        test_list = []
        test_list.extend(left_list)
        test_list.append(value_temp)
        test_list.extend(right_list)
        label = 1
        for i in range(len_of_list - 1):
            if list[i+1] < list[i]:
                label = 0
        if label == 1:
            return test_list
        else:
            left_list = quick_sort(left_list)
            right_list = quick_sort(right_list)
            result_list = []
            result_list.extend(left_list)
            result_list.append(value_temp)
            result_list.extend(right_list)
            return result_list
random.seed(123456)
List1 = random.randint(-16, 16, size=16)
print(quick_sort(list(List1)))

运行结果如下:

[-16, -15, -12, -8, -6, -6, -6, -5, -5, -4, -1, 1, 2, 7, 8, 11]

我采用了递归的思路来实现快速排序。快排首先从列表中随机选取一个元素,保持元素的位置不动, 将比这个元素小的其他元素放入left_list,比这个元素大的其他元素放入right_list,从而将原问题拆分成了两个相同的子问题。然后再对left_list和right_list分别用相同的思路进行排序,直到left_list和right_list都有序。此时,将left_list和选出的元素以及right_list合并为一个有序列表并返回。在这个过程中需要考虑一些特殊情况,比如待排序的列表的长度小于等于1,那么在这种情况下就没有排序的必要,直接返回原来的列表就可以了。另外就是递归停止的条件是划分后的left_list和选出的元素以及right_list组成的test_list是否已经排好序,如果已经排好序,则停止递归直接返回,否则继续。在这里,其实可以选择分别判断left_list和right_list是否已经有序,如果已经有序则没有必要对已经有序的list继续递归排序,我这里的处理有一点粗糙,有一定可能存在冗余的运算。最后,快排的平均时间复杂度是O(n*logn), 最坏时间复杂度为O(n^2)。

二、归并排序

首先贴代码:

def merge_sort(list1, list2):
    len_of_list1 = len(list1)
    len_of_list2 =len(list2)
    index_1 = 0
    index_2 = 0
    result_list = []
    if len_of_list1 == 0 and len_of_list2 ==0:
        return []
    elif len_of_list1 == 0 and len_of_list2 != 0:
        return list2
    elif len_of_list1 != 0 and len_of_list2 == 0:
        return list1
    while True:
        if index_1 == len_of_list1 or index_2 == len_of_list2:
            break
        if list1[index_1] <= list2[index_2]:
            result_list.append(list1[index_1])
            index_1 += 1
        else:
            result_list.append(list2[index_2])
            index_2 += 1
    if index_1 == len_of_list1:
        for i in range(index_2, len_of_list2):
            result_list.append(list2[i])
        return result_list
    else:
        for i in range(index_1, len_of_list1):
            result_list.append(list1[i])
        return result_list
random.seed(123456)
List1 = random.randint(-16, 16, size=16)
List2 = random.randint(-50, 50, size=8)#设置随机数种子,保证每次运行结果一致
print(quick_sort(list(List1)))
print(quick_sort(list(List2)))
print(merge_sort(quick_sort(list(List1)), quick_sort(list(List2))))

 

运行结果如下:

[-16, -15, -12, -8, -6, -6, -6, -5, -5, -4, -1, 1, 2, 7, 8, 11]
[-36, -30, -16, -3, 0, 20, 25, 36]
[-36, -30, -16, -16, -15, -12, -8, -6, -6, -6, -5, -5, -4, -3, -1, 0, 1, 2, 7, 8, 11, 20, 25, 36]

归并排序的原理比较简单,输入为两个已经排好序的有序列表,然后合并为一个有序列表。数据结构与算法那本书里的图生动形象,我这里就不说废话了, 直接看下代码就可以了。

 

 

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

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值