排序算法实现与总结Python/Java
2018-03-15 15:39
826 查看
参考
Python:http://wuchong.me/blog/2014/02/09/algorithm-sort-summary/
Java:
https://www.cnblogs.com/10158wsj/p/6782124.html?utm_source=tuicool&utm_medium=referral
稳定性解释:
https://baike.baidu.com/item/%E6%8E%92%E5%BA%8F%E7%AE%97%E6%B3%95%E7%A8%B3%E5%AE%9A%E6%80%A7/9763250?fr=aladdin
性能分析与适应场景:
http://blog.csdn.net/p10010/article/details/49557763
动画:
http://blog.csdn.net/tobeandnottobe/article/details/7192953
http://www.webhek.com/post/comparison-sort.html
性能
只需记住一句话(快些选一堆美女一起玩儿)是不稳定的,其他都是稳定的。
初始数据越无序,快速排序越好。
实现
冒泡排序
Python:def bubble_sort(array): n = len(array) for i in range(n): # i从0到n for j in range(1, n-i): # 1开始,即j-1=0开始 if array[j-1] > array[j]: array[j+1], array[j] = array[j], array[j+1] return array #优化1:某一趟遍历如果没有数据交换,则说明已经排好序了,因此不用再进行迭代了。 #用一个标记记录这个状态即可。 def bubble_sort2(ary): n = len(ary) for i in range(n): flag = 1 #标记 for j in range(1,n-i): if ary[j-1] > ary[j] : ary[j-1],ary[j] = ary[j],ary[j-1] flag = 0 if flag : #全排好序了,直接跳出 break return ary #优化2:记录某次遍历时最后发生数据交换的位置,这个位置之后的数据显然已经有序了。 # 因此通过记录最后发生数据交换的位置就可以确定下次循环的范围了。 def bubble_sort3(ary): n = len(ary) k = n #k为循环的范围,初始值n for i in range(n): flag = 1 for j in range(1,k): #只遍历到最后交换的位置即可 if ary[j-1] > ary[j] : ary[j-1],ary[j] = ary[j],ary[j-1] k = j #记录最后交换的位置 flag = 0 if flag : break return ary
Java:
public void bubble_sort(int [] a) { int n = a.length; for(int i=0;i<n;i++) { for(int j=1;j<n-i;j++) { if (a[j-1] > a[j]) { int temp = a[j-1]; a[j-1] = a[j]; a[j] = temp; } } } } //两种优化不写了
选择排序
Python:def selection_sort(array): n = len(array) for i in range(n): minIndex = i for j in range(i+1, n): if array[j] < array[minIndex]: minIndex = j array[i], array[minIndex] = array[minIndex], array[i] # 或者使用minNum存储数值,避免每次都读array[minIndex],但如果每次都存储新的minNum,也会有损耗。 def selection_sort(array): n = len(array) for i in range(n): minNum = array[i] minIndex = i for j in range(i+1, n): if array[j] < minNum: minIndex = j minNum = array[j] array[i], array[minIndex] = array[minIndex], array[i]
Java:
public void selection_sort(int [] a) { int n = a.length; for(int i=0;i<n;i++) { int 4000 minIndex = i; for(int j=i;j<n;j++) { if (a[j] < a[minIndex]) { minIndex = j; } } int temp = a[i]; a[i] = a[minIndex]; a[minIndex] = temp; } }
插入排序
Python:def insert_sort(array): n = len(array) for i in range(1,n): # 从第二个数开始 if array[i-1] > array[i]: # 前面比后面小 num = array[i] index = i for j in range(i-1, -1, -1): if array[j] > num: array[j+1] = array[j] index = j else: # 找到位置,插入 array[index] = num break
Java:
public void insert_sort(int [] a) { int n = a.length; for(int i=1;i<n;i++) { if (a[i-1] > a[i]) { int num = a[i]; int index = i; for(int j=i-1;j>-1;j--) { if (a[j] > num) { a[j+1] = a[j]; index = j; } else { a[index] = num; break; } } } } }
希尔排序(递减增量排序算法,实质是分组插入排序)
Python:def shell_sort(ary): n = len(ary) gap = round(n/2) # 初始步长 , 用round取整(注意0.5向下取) while gap > 0 : for i in range(gap,n): # 每一列进行插入排序 , 从gap 到 n-1 temp = ary[i] j = i print(temp, j) while ( j >= gap and ary[j-gap] > temp ): # 插入排序 ary[j] = ary[j-gap] j = j - gap ary[j] = temp gap = round(gap/2) # 重新设置步长 return ary
Java:
public void shell_sort(int [] a) { int n = a.length; int gap = n / 2; while (gap > 0) { for (int i=gap;i<n;i++) { int temp = a[i]; int j = i; while (j>=gap && a[j-gap] > temp) { a[j] = a[j-gap]; j = j - gap; } a[j] = temp; } gap = gap / 2; } }
归并排序(递归合并)
Python:def merge_sort(array): # 递归 if len(array) <= 1: return array # python每次都是新的数组,可以用数组长度小于等于1来判断 num = int(len(array) / 2) # int不然是浮点数,切片报错 left = merge_sort(array[:num]) right = merge_sort(array[num:]) return merge(left, right) def merge(left, right): # 合并 l,r = 0,0 result = [] while l < len(left) and r < len(right): if left[l] < right[r]: result.append(left[l]) l = l + 1 else: result.append(right[r]) r += 1 # 一边没有之后,加上所有的 result += left[l:] result += right[r:] return result
Java:
//注意:新建的temp长度和原数组是一样的,所以额外空间是O(n),temp数组一开始并未赋值,在合并时慢慢给其填充数值,所以说一共只有一个temp数组 public void mergeSort(int[] arr) { mergeSort(arr, new int[arr.length], 0, arr.length - 1); } private static void mergeSort(int[] arr, int[] temp, int left, int right) { if (left < right) { // Java则通过左右指针来判断 int center = (left + right) / 2; mergeSort(arr, temp, left, center); // 左边 mergeSort(arr, temp, center + 1, right); // 右边 merge(arr, temp, left, center + 1, right); // 合并两个有序 } } private static void merge(int[] arr, int[] temp, int leftPos, int rightPos, int rightEnd) { int leftEnd = rightPos - 1; // 左边结束下标 int tempPos = leftPos; // 从左边开始算 int numEle = rightEnd - leftPos + 1; // 元素个数 while (leftPos <= leftEnd && rightPos <= rightEnd) { if (arr[leftPos] <= arr[rightPos]) temp[tempPos++] = arr[leftPos++]; else temp[tempPos++] = arr[rightPos++]; } while (leftPos <= leftEnd) { // 左边如果有剩余 temp[tempPos++] = arr[leftPos++]; } while (rightPos <= rightEnd) { // 右边如果有剩余 temp[tempPos++] = arr[rightPos++]; } // 将temp复制到arr,覆盖原来这里的位置 for (int i = 0; i < numEle; i++) { arr[rightEnd] = temp[rightEnd]; rightEnd--; } }
快速排序
http://blog.csdn.net/morewindows/article/details/6684558Python:
def quick_sort(ary): return _quick_sort(ary, 0, len(ary)-1) def _quick_sort(ary, left, right): if left >= right: return ary key = ary[left] # 每次都选最左边为key lp = left rp = right while (lp < rp): while ary[rp] >= key and lp < rp: rp -= 1 while ary[lp] <= key and lp < rp: lp += 1 ary[lp], ary[rp] = ary[rp], ary[lp] ary[left], ary[lp] = ary[lp], ary[left] # 这里不能用key,是交换数组内数字 _quick_sort(ary, left, lp-1) _quick_sort(ary, rp+1, right) return ary
Java:
public void quick_sort(int[] ary) { _quick_sort(ary, 0, ary.length-1); } public void _quick_sort(int[] ary, int left, int right) { if (left < right) { int key = ary[left]; int lp = left; int rp = right; while (lp < rp) { while (ary[rp] >= key && lp < rp ) { rp--; } while (ary[lp] <= key && lp < rp ) { lp++; } int temp = ary[lp]; ary[lp] = ary[rp]; ary[rp] = temp; } int temp = ary[lp]; ary[lp] = ary[left]; ary[left] = temp; _quick_sort(ary, left, lp-1); _quick_sort(ary, rp+1, right); } }
堆排序
http://blog.csdn.net/minxihou/article/details/51850001https://www.2cto.com/kf/201609/549335.html
例题:相当帮助理解
https://www.nowcoder.com/test/question/done?tid=14276624&qid=56294#summary
堆可以分为大根堆和小根堆,这里用最大堆的情况来定义操作:
(1)最大堆调整(MAX_Heapify):将堆的末端子节点作调整,使得子节点永远小于父节点。这是核心步骤,在建堆和堆排序都会用到。比较i的根节点和与其所对应i的孩子节点的值。当i根节点的值比左孩子节点的值要小的时候,就把i根节点和左孩子节点所对应的值交换,当i根节点的值比右孩子的节点所对应的值要小的时候,就把i根节点和右孩子节点所对应的值交换。然后再调用堆调整这个过程,可见这是一个递归的过程。
(2)建立最大堆(Build_Max_Heap):将堆所有数据重新排序。建堆的过程其实就是不断做最大堆调整的过程,从len/2出开始调整,一直比到第一个节点。
(3)堆排序(HeapSort):移除位在第一个数据的根节点,并做最大堆调整的递归运算。堆排序是利用建堆和堆调整来进行的。首先先建堆,然后将堆的根节点选出与最后一个节点进行交换,然后将前面len-1个节点继续做堆调整的过程。直到将所有的节点取出,对于n个数我们只需要做n-1次操作。
Python:
def MAX_Heapify(heap, HeapSize, root): # 在堆中做结构调整使得父节点的值大于子节点 left = 2 * root + 1 right = left + 1 larger = root if left < HeapSize and heap[larger] < heap[left]: larger = left if right < HeapSize and heap[larger] < heap[right]: larger = right if larger != root: # 如果做了堆调整:则larger的值等于左节点或者右节点的,这个时候做对调值操作 heap[larger],heap[root] = heap[root],heap[larger] MAX_Heapify(heap, HeapSize, larger) def Build_MAX_Heap(heap): # 构造一个堆,将堆中所有数据重新排序 HeapSize = len(heap) for i in range((HeapSize -2)//2,-1,-1): # 从后往前出数 '//' got integer MAX_Heapify(heap,HeapSize,i) def HeapSort(heap): # 将根节点取出与最后一位做对调,对前面len-1个节点继续进行对调整过程。 Build_MAX_Heap(heap) for i in range(len(heap)-1,-1,-1): heap[0],heap[i] = heap[i],heap[0] MAX_Heapify(heap, i, 0) return heap
Java:
有空补
相关文章推荐
- paip.提升安全性----Des加密 java php python的实现总结
- 总结java实现八大排序算法及之间的关系
- 经典排序算法总结与实现 ---python
- 各种排序算法python和java实现(二)
- 八种排序算法总结(Java实现)
- paip.提升安全性----Des加密 java php python的实现总结
- 排序算法终结总结<Java实现>
- Java基础学习总结(28)——Java对各种排序算法的实现
- 排序算法总结(冒泡排序、直接插入排序、希尔排序)(python实现)
- 排序算法总结&&java代码实现
- 排序算法总结(简单选择排序、堆排序)(python实现)
- 排序算法的Java实现和总结
- Java基础学习总结(28)——Java对各种排序算法的实现
- 排序算法总结以及python代码实现
- 各种排序算法python和java实现(一)
- Java基础学习总结(28)——Java对各种排序算法的实现
- 排序算法总结与java实现
- Python实现各种排序算法的代码示例总结
- 排序算法总结-python实现
- 经典排序算法java实现总结