系列文章目录
【LeetCode算法题】各类基础排序算法的Python实现
文章目录
- 系列文章目录
- 【LeetCode算法题】各类基础排序算法的Python实现
- 1. 直接插入排序
- 2. 折半插入排序
- 3. 选择排序
- 4. 冒泡排序
- 5. 归并排序算法
- 6.快速排序
- 7. 堆排序
- 总结
对于直接插入排序、折半插入排序、选择排序、冒泡排序、归并排序,快速排序、堆排序算法的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 matdef 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):returnpivot_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)。