【LeetCode算法题】各类排序算法的Python实现

发布时间:2024年01月18日

系列文章目录

【LeetCode算法题】各类基础排序算法的Python实现

??对于直接插入排序、折半插入排序、选择排序、冒泡排序、归并排序,快速排序、堆排序算法的Python实现进行记录。
注:所有LeetCode系列文章均是为了复习作为记录,思维可能有跳跃,有疑问欢迎一起讨论。


1. 直接插入排序

??将列表分为有序表 nums[ : i] 与无序表 nums[i : ] 两部分,通过“比较” +“移动” 两步操作将 nums[i] 放到有序表对应部分,向后迭代 i 至列表尾部,完成排序。

for i in range(len(nums_1)):
    for j in range(i):
        if (nums_1[i] < nums_1[j]):
            temp = nums_1[i];
            nums_1[j + 1: i + 1] = nums_1[j: i];
            nums_1[j] = temp;
print(nums_1)

2. 折半插入排序

??直接插入排序中的 “比较” 实际上为找出 nums[i] 在有序表中的位置,可以将顺序查找优化为折半查找,注意最终查找的位置与 low 和 high 的关系。

for i in range(len(nums_2)):
    low = 0;
    high = i - 1;
    while (low <= high):
        mid = low + (high - low) // 2;
        if (nums_2[mid] >= nums_2[i]):
            high = mid - 1;
        else:
            low = low + 1;
    temp = nums_2[i];
    nums_2[low + 1 : i + 1] = nums_2[low : i];
    nums_2[low] = temp;
print(nums_2)

3. 选择排序

??依次选出列表中最小的数,插入表前。

for i in range(len(nums_3)):
    j = i;
    temp_index = j;
    temp = nums_3[j];
    while (j < len(nums_3)):
        if (nums_3[j] < temp):
            temp_index = j;
            temp = nums_3[j];
        j = j + 1;
    nums_3[temp_index] = nums_3[i];
    nums_3[i] = temp;
print(nums_3)

4. 冒泡排序

??依次交换,大数向后移动,每轮确定一个数的最终位置,当该轮未发生交换时,可提前结束(用tag记录);

for i in range(len(nums_4)):
    tag = 0;
    for j in range(len(nums_4) - i - 1):
        if (nums_4[j] > nums_4[j + 1]):
            tag = 1;
            nums_4[j], nums_4[j + 1] = nums_4[j + 1], nums_4[j];
    if (tag == 0):
        break
print (nums_4)

5. 归并排序算法

??二路归并,左半部分数组排序,右半部分数组排序,最后合并。

def merge(left, right):
    """
    :param left: 有序数组;
    :param right: 有序数组;
    :return: 返回合并后的有序数组。
    """
    mat = [];
    i, j = 0, 0;
    len_left = len(left);
    len_right = len(right);
    while ((i < len_left) & (j < len_right)):
        if (left[i] < right[j]):
            mat.append(left[i]);
            i += 1;
        else:
            mat.append(right[j]);
            j += 1;
    mat.extend(left[i : ]);
    mat.extend(right[j : ]);
    return mat

def merge_sort(nums_5):
    if len(nums_5) <= 1:
        return nums_5;
    mid = len(nums_5) // 2;
    left = merge_sort(nums_5[ : mid]);
    right = merge_sort(nums_5[mid : ]);
    return merge(left, right);

6.快速排序

??每轮选出一个 pivot ,使其左边的小于 pivot ,右边大于 pivot 。每轮比较过后,pivot 与 right_idx 的值进行互换。

def quick_sort(array, start_idx, end_idx):
    if ((end_idx - start_idx) < 1):
        return
    pivot_idx = start_idx;
    left_idx = start_idx + 1;
    right_idx = end_idx;
    while (left_idx <= right_idx):
        if ((array[left_idx] > array[pivot_idx]) & (array[right_idx] < array[pivot_idx])):
            array[left_idx], array[right_idx] = array[right_idx], array[left_idx];
        if (array[left_idx] < array[pivot_idx]):
            left_idx += 1;
        if (array[right_idx] > array[pivot_idx]):
            right_idx -= 1;
    array[right_idx], array[pivot_idx] = array[pivot_idx], array[right_idx];
    quick_sort(array, start_idx, right_idx - 1);  # 这里不能用切片,需要对原数组进行修改。
    quick_sort(array, left_idx, end_idx);

7. 堆排序

??数组与树联系的关键在于, 堆排序主要分为两步操作:建堆 + 弹出。

def Sort(array):
    for i in range(1, len(array)):
        father = int((i - 1) / 2);
        while ((i != 0) and (array[father] > array[i])):         # 逻辑运算符要加括号。
            array[father], array[i] = array[i], array[father];
            i = father;
            father = int((i - 1) / 2);
    return array;

def heap_sort(array):
    mat = [];
    while(len(array) != 0):
        Sort(array);
        mat.append(array[0]);
        array = array[1 : ];
    return mat;

print(heap_sort(nums_7))

总结

??简单选择排序、希尔排序、快速排序、堆排序为不稳定算法;快速排序、堆排序、归并排序时间复杂度为:O(nlogn)。

文章来源:https://blog.csdn.net/qq_53271322/article/details/135621354
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。