【程序员笔试面试必会——排序①】Python实现 冒泡排序、选择排序、插入排序、归并排序、快速排序、堆排序、希尔排序
2018-01-12 15:13
411 查看
最近在准备笔试题和面试题,把学到的东西整理出来,一来是给自己留个笔记,二来是帮助大家学习。
题目:
给定一个int数组A及数组的大小n,请返回排序后的数组。
测试样例:
代码示例:
冒泡排序:O(n^2)
最基本的排序,不多解释。
选择排序:O(n^2)
想象成每次从一大堆数里面选出最小的数放在左边,重复直到这一大对数都被选完。
插入排序:O(n^2)
想象成打麻将时,摸到一个排插入到已有的麻将里边。选择排序从左边第二个牌开始,与左边的牌比较,如果比左边的小就与其交换位置,依次重复此步骤,直到排序完所有的牌。
归并排序:O(n*log n)
分治法思想。把所有的数看成长度为1的有序区间:[1],[2],[3],[5],[2],[3],再将相邻的区间合并成为最大长度为2的有序区间:[1,2],[3,5],[2,3],再合并成为最大长度为4的有序区间:[1,2,3,5],[2,3],再合并:[1,2,2,3,3,5]。
快速排序:O(n*log n)
从这些数中随意选一个数,小于这个数的放在它左边,大于它的放右边;再在这左右两边的一堆数重复使用这个方法,直到排序结束。
堆排序:
在这里我们借用wiki的定义来说明: 通常堆是通过一维数组来实现的,在阵列起始位置为0的情况中
(1)父节点i的左子节点在位置(2*i+1);
(2)父节点i的右子节点在位置(2*i+2);
(3)子节点i的父节点在位置floor((i-1)/2);
希尔排序:
插入排序是希尔排序的一种特殊情况,当希尔排序的初始步长为1时,即为插入排序。
题目:
给定一个int数组A及数组的大小n,请返回排序后的数组。
测试样例:
输入:[1,2,3,5,2,3],6
返回:[1,2,2,3,3,5]
代码示例:
冒泡排序:O(n^2)
最基本的排序,不多解释。
class BubbleSort: def bubbleSort(self, A, n): for x in xrange(n): for y in xrange(n-x-1): if A[y] > A[y+1]: A[y], A[y+1] = A[y+1], A[y] return A
选择排序:O(n^2)
想象成每次从一大堆数里面选出最小的数放在左边,重复直到这一大对数都被选完。
class SelectionSort: def selectionSort(self, A, n): for i in xrange(n-1): min_index = i for j in xrange(i+1, n): if A[min_index] > A[j]: min_index = j if min_index != i: A[i], A[min_index] = A[min_index], A[i] return A
插入排序:O(n^2)
想象成打麻将时,摸到一个排插入到已有的麻将里边。选择排序从左边第二个牌开始,与左边的牌比较,如果比左边的小就与其交换位置,依次重复此步骤,直到排序完所有的牌。
class InsertionSort: def insertionSort(self, A, n): for i in xrange(1, n): tmp = A[i] j = i - 1 while tmp < A[j] and j >= 0: A[j+1] = A[j] j -= 1 A[j+1] = tmp return A
归并排序:O(n*log n)
分治法思想。把所有的数看成长度为1的有序区间:[1],[2],[3],[5],[2],[3],再将相邻的区间合并成为最大长度为2的有序区间:[1,2],[3,5],[2,3],再合并成为最大长度为4的有序区间:[1,2,3,5],[2,3],再合并:[1,2,2,3,3,5]。
class MergeSort: def mergeSort(self, A, n): if n <= 1: return A half = n / 2 left = self.mergeSort(A[:half], half) right = self.mergeSort(A[half:], n-half) result = [] i = j = 0 while i < len(left) and j < len(right): if left[i] < right[j]: result.append(left[i]) i += 1 else: result.append(right[j]) j += 1 result += left[i:] result += right[j:] return result
快速排序:O(n*log n)
从这些数中随意选一个数,小于这个数的放在它左边,大于它的放右边;再在这左右两边的一堆数重复使用这个方法,直到排序结束。
class QuickSort: def quickSort(self, A, n=None): if not A: return [] else: key = A[0] # 固定每次选择最左边的数 left = self.quickSort([n for n in A[1:] if n <= key]) right = self.quickSort([n for n in A[1:] if n > key]) return left + [key] + right
堆排序:
在这里我们借用wiki的定义来说明: 通常堆是通过一维数组来实现的,在阵列起始位置为0的情况中
(1)父节点i的左子节点在位置(2*i+1);
(2)父节点i的右子节点在位置(2*i+2);
(3)子节点i的父节点在位置floor((i-1)/2);
# -*- coding:utf-8 -*- class HeapSort: def heapSort(self, A, n): # 创建大根堆 for i in xrange(n/2 + 1, -1, -1): self.max_heap_fix(A, i, n) # 堆排序 for i in xrange(n-1, -1, -1): A[0], A[i] = A[i], A[0] self.max_heap_fix(A, 0, i) return A def max_heap_fix(self, A, i, n): """ :param A: 大根堆、一维数组 :param i: 预修复的子树根节点 :param n: 大根堆总的元素数量 """ j = i * 2 + 1 # i的左子节点下标 # 当i的左子节点存在时 while j < n: # 当i的右子节点存在,且大于i的左子节点 if j + 1 < n and A[j] < A[j+1]: j += 1 # 当i的左右子节点都小于i时,修复大根堆结束 if A[j] < A[i]: break # 当i的子节点大于i时,交换节点 A[i], A[j] = A[j], A[i] i = j # 将i移向于i交换的节点 j = i * 2 + 1 # i的左子节点下标
希尔排序:
插入排序是希尔排序的一种特殊情况,当希尔排序的初始步长为1时,即为插入排序。
class ShellSort: def shellSort(self, A, n): step = n / 2 while step > 0: for i in xrange(step, n): tmp = A[i] while i >= step and tmp < A[i-step]: A[i] = A[i-step] i -= step A[i] = tmp step = step / 2 return A
相关文章推荐
- 笔试面试最常涉及到的12种排序算法(包括插入排序、二分插入排序、希尔排序、选择排序、冒泡排序、鸡尾酒排序、快速排序、堆排序、归并排序、桶排序、计数排序和基数排序)进行了详解。每一种算法都有基本介绍、算
- 元素排序几种常用的排序算法的分析及java实现(希尔排序,堆排序,归并排序,快速排序,选择排序,插入排序,冒泡排序)
- 几种常用的排序算法的分析及java实现(希尔排序,堆排序,归并排序,快速排序,选择排序,插入排序,冒泡排序)
- 插入排序、冒泡排序、选择排序、希尔排序、快速排序、归并排序、堆排序和LST基数排序——C++实现
- 冒泡排序、选择排序、插入排序、希尔排序、归并排序、快速排序、堆排序java实现
- 几种常用的排序算法的分析及java实现(希尔排序,堆排序,归并排序,快速排序,选择排序,插入排序,冒泡排序)
- 各种排序算法实现——基数排序、归并排序、插入排序、冒泡排序、选择排序、快速排序、堆排序、希尔排序
- 算法导论之插入排序,选择排序,归并排序,冒泡排序,希尔排序,堆排序,快速排序的c语言实现
- 各种排序算法总结----基数排序、归并排序、插入排序、冒泡排序、选择排序、快速排序、堆排序、希尔排序
- 选择排序、快速排序、希尔排序、堆排序不是稳定的排序算法,而冒泡排序、插入排序、归并排序和基数排序
- 直通BAT-排序1(冒泡排序、选择排序、插入排序、归并排序、快速排序、堆排序、希尔排序)
- 常见比较排序算法的实现(归并排序、快速排序、堆排序、选择排序、插入排序、希尔排序)
- Python实现冒泡排序、选择排序、插入排序、快速排序、归并排序、二分法查找算法(基于《算法导论》伪代码)
- 选择排序、快速排序、希尔排序、堆排序不是稳定的排序算法,而冒泡排序、插入排序、归并排序和基数排序是稳定的排序算法。
- java实现七种排序 (插入排序, 希尔排序, 插入排序, 快速排序, 简单选择排序, 堆排序, 归并排序)
- 几种常见排序算法之Java实现(插入排序、希尔排序、冒泡排序、快速排序、选择排序、归并排序)
- 牛客网Java刷题知识点之插入排序(直接插入排序和希尔排序)、选择排序(直接选择排序和堆排序)、冒泡排序、快速排序、归并排序和基数排序(博主推荐)
- 插入排序、二分插入排序、希尔排序、选择排序、冒泡排序、鸡尾酒排序、快速排序、堆排序、归并排序
- 面试珠玑 快速排序、希尔排序、插入排序、选择排序、归并排序、堆排序总结
- 插入排序、冒泡排序、选择排序、希尔排序、快速排序、归并排序、堆排序和LST基数排序——JAVA实现