排序算法总结(下)
2017-05-12 13:07
204 查看
4.堆排序
思路:堆就是一个完全二叉树(小顶堆),主要解决两个问题:
如何将n个待排序的数构建成堆
输出堆顶元素之后如何调整剩下的n-1个元素,使之成为新的堆
时间复杂度:O(nlogn)
代码实现:
private static class HeapSort { public HeapSort(int a[]) { buildMaxHeapify(a); heapSort(a); System.out.println(""); System.out.println("****4.堆排序之后:****"); for (int i = 0; i < a.length; i++) { System.out.print(a[i] + ","); } } // 构建初始最大堆 // 假设长度为8 那么 // 第一个父节点就是a[3] 左结点为:a[7] // 第二个父节点为:a[1] 左节点为:a[3] 右结点为:a[4] // 第三份父节点为:a[2] 左节点为:a[5] 右结点为:a[6] public static void buildMaxHeapify(int a[]) { System.out.println("字符串的长度为:" + a.length); int startIndex = getParentIndex(a.length - 1); for (int i = startIndex; i >= 0; i--) { maxHeapify(a, a.length, i); } } /** * * @param a * 数组 * @param length * 数据长度 * @param index * 当前的父节点 */ private static void maxHeapify(int[] a, int length, int index) { // 与当前左右结点进行比较 int left = getChildLeftIndex(index); int right = getChildRightIndex(index); // 进行左右节点值的对比 int largest = index; if (left < length && a[left] > a[index]) { largest = left; } if (right < length && a[right] > a[largest]) { largest = right; } if (largest != index) { int temp = a[index]; a[index] = a[largest]; a[largest] = temp; // 整理节点 maxHeapify(a, length, largest); } } // 父节点的位置 private static int getParentIndex(int i) { return i / 2; } // 左孩子的位置 private static int getChildLeftIndex(int index) { return index * 2 + 1; } // 右孩子的位置 private static int getChildRightIndex(int index) { return index * 2 + 2; } /** * 这个函数的含义就是: 将排好的最大堆的堆顶和最后一个交换再进行最大堆排序 排序:最大值放在末尾,再次进行排序 * * @param a */ public static void heapSort(int a[]) { for (int i = a.length - 1; i > 0; i--) { int temp = a[0]; a[0] = a[i]; a[i] = temp; maxHeapify(a, i, 0); } } }
5.冒泡排序
思路:就是不断的两两比较时间复杂度:O(n^2)
代码实现
private static class BubbleSort { //简单的冒泡排序 public static void bubbleSort_A(int a[]) { for (int i = 0; i < a.length; i++) { for (int j = 0; j < a.length-i- 1; j++) { if (a[j] > a[j + 1]) { Swap(a, j, j + 1); } } } } //改进的冒泡,添加了标记 public static void bubbleSort_B(int a[]){ int n = a.length-1; while(n>0){ int pos = 0; for (int i = 0; i < n; i++) { if(a[i]>a[i+1]){ pos = i; Swap(a, i, i+1); } } n = pos; } } }
6.快速排序
思路:选择一个基准元素
通过一次快排序将待排序数分为两个部分,一部分比基准数小,一部分比基准数大
然后接着对这两部分进行相同的操作,直到序列有序
时间复杂度:O(nlogn)
空间复杂度: O(nlogn)
快速排序代码
private static class QuickSort{ public static void quickSort(int a[],int low,int high){ if(low<high){ int privotLoc = partition(a,low,high); quickSort(a, low, privotLoc-1); quickSort(a, privotLoc+1, high); } } private static int partition(int[] a, int low, int high) { int privotKey = a[low]; while(low<high){ while(low<high && a[high]>=privotKey)--high;//从后半部分向前扫描 a[low] = a[high]; while(low<high && a[low]<=privotKey)++low; //从前部分扫描 a[high] = a[low]; } a[high] = privotKey; return low; } }