1.冒泡排序(BubbleSort):
冒泡排序算法的流程如下:
(1)比较相邻的元素。
(2)对每一对相邻元素作同样的行为,从开始第一对到结尾的最后一对。
(3)针对所有的元素重复以上的步骤,每一趟排好一个数。
复杂度:O(n^2)
代码实现:
- public class Code_00_BubbleSort {
- public static void bubbleSort(int[] arr) {
- if(arr == null || arr.length<2) {
- return;
- }
- for(int e = arr.length-1;e>0;e--) {
- for(int i = 0;i<e;i++){
- if(arr[i]>arr[i+1])
- swap(arr,i,i+1);
- }
- }
- }
- public static void swap(int[] arr, int i, int j) {
- int temp = arr[i];
- arr[i] = arr[j];
- arr[j] = temp;
- }
2.选择排序(SelectionSort):
(1)算法思想: 每次取一个最小值。
(2)复杂度:O(n^2)。
代码实现:
- public class Code_02_SelectionSort {
- public static void selectionSort(int[] arr) {
- if (arr == null || arr.length < 2) {
- return;
- }
- for(int i = 0;i<arr.length-1;i++) {
- int midIndex = i;
- for(int j =i+1;j<arr.length;j++) {
- midIndex = arr[j] < arr[midIndex] ? j : midIndex;
- }
- swap(arr,i,midIndex);
- }
- }
- public static void swap(int[] arr, int i, int j) {
- int tmp = arr[i];
- arr[i] = arr[j];
- arr[j] = tmp;
}
3.插入排序(InsertionSort):
代码实现:
- Code_01_InsertionSort {
- public static void inserttionSort(int[] arr) {
- if(arr == null || arr.length<2 ) {
- return ;
- }
- for(int i = 1;i<arr.length;i++) {
- for(int j = i-1;j>=0 && arr[j]>arr[j+1];j--) {
- swap(arr,j,j+1);
- }
- }
- }
- public static void swap(int[] arr,int i,int j) {
- int temp = arr[i];
- arr[i] = arr[j];
- arr[j] = temp;
- }
复杂度:
1.最佳情况:T(n) = O(n) ;
2.最坏情况:T(n) = O(n^2);
3.平均情况:T(n) = O(n^2);
4.归并排序(MergeSort):
归并排序:
思想:运用分治法思想解决排序问题。
(1)设定两个指针,分别指向待排序列的最初位置和末尾位置。
(2)比较两个指针所指向的元素,选择相对小的元素放入到合并空间,并移动指针到下一个位置。
(3)重复步骤(3)直到某一指针达到尾部。
(4)将另一序列剩下的所有元素直接复制到尾部。
代码如下:
- public class Code_03_MergeSort {
- public static void mergeSort(int[] arr) {
- if(arr == null || arr.length<2) {
- return;
- }
- mergeSort(arr,0,arr.length-1);
- }
- public static void mergeSort(int[] arr, int l, int r) {
- if (l == r) {
- return;
- }
- int mid = l + ((r - l) >> 1);
- mergeSort(arr,l,mid);
- mergeSort(arr,mid+1,r);
- merge(arr,l,mid,r);
- //T(N) =2(N/2)+O(N)
- }
- public static void merge(int[] arr, int l, int m, int r) {
- int[] help = new int[r-l+1];
- int i = 0;
- int p1 = l;
- int p2 = m+1;
- while (p1<=m && p2<=r ) {
- help[i++] = arr[p1] < arr[p2] ? arr[p1++] : arr[p2++];
- }
- while (p1 <= m) {
- help[i++] = arr[p1++];
- }
- while (p2 <= r) {
- help[i++] = arr[p2++];
- }
- for (i = 0; i < help.length; i++) {
- arr[l+i] = help[i];
- }
- }
复杂度: O(nlgn)
6 快速排序(QuickSort):
快速排序:
算法思想:分治法+递归
算法步骤描述:
(1)从数列中挑出一个元素,称为 “基准”
(2)重新排序数列,所有元素比基准值小的摆放在基准左边,所有元素比基准值大的摆在基准的右边(相同的数可以到任一边)。在这个分区退出之后,该基准就处于数列的中间位置。这个称为分区(partition)操作。
(3)递归地(recursive)把小于基准值元素的子数列和大于基准值元素的子数列排序。
代码实现:
- public class Code_05_QuickSort {
- public static void quickSort(int [] arr) {
- if(arr == null || arr.length<2) {
- return;
- }
- quickSort(arr,0,arr.length-1);
- }
- public static void quickSort(int [] arr,int l,int r) {
- if(l<r) {
- int[] p = partition(arr,l,r);
- quickSort(arr, l, p[0] - 1);
- quickSort(arr, p[1] + 1, r);
- }
- }
- private static int[] partition(int[] arr, int l, int r) {
- int less = l-1;
- int more = r;
- while(l<more) {
- if(arr[l]<arr[r]) {
- swap(arr,++less,l++);
- }else if(arr[l]>arr[r]) {
- swap(arr,--more,l);
- }else {
- l++;
- }
- }
- swap(arr,more,r);
- return new int[] {less+1,more};
- }
- private static void swap(int[] arr, int i, int j) {
- int temp = arr[i];
- arr[i] = arr[j];
- arr[j] = temp;
- }
复杂度:
最坏运行时间:O(n^2)
最佳运行时间:O(nlgn)
堆排:
堆排序:
步骤:
堆排序利用了大根堆,堆顶记录的关键字最大这一特征,使得在当前无序区中选取最大关键字的记录变得简单。
代码实现:
- public class Code_07_HeapSort {
- public static void heapSort(int[] arr) {
- if (arr == null || arr.length < 2) {
- return;
- }
- for (int i = 0; i < arr.length; i++) {
- heapInsert(arr, i);
- }
- int size = arr.length;
- swap(arr, 0, --size);
- while (size > 0) {
- heapify(arr, 0, size);
- swap(arr, 0, --size);
- }
- }
- public static void heapInsert(int[] arr, int index) {
- while (arr[index] > arr[(index - 1) / 2]) {
- swap(arr, index, (index - 1) / 2);
- index = (index - 1) / 2;
- }
- }
- public static void heapify(int[] arr, int index, int size) {
- int left = index * 2 + 1;
- while (left < size) {
- int largest = left + 1 < size && arr[left + 1] > arr[left] ? left + 1 : left;
- largest = arr[largest] > arr[index] ? largest : index;
- if (largest == index) {
- break;
- }
- swap(arr, largest, index);
- index = largest;
- left = index * 2 + 1;
- }
- }
- public static void swap(int[] arr, int i, int j) {
- int tmp = arr[i];
- arr[i] = arr[j];
- arr[j] = tmp;
- }
复杂度:
O(nlgn)
说明:用小根堆排序与利用大根堆类似,只不过其排序结果是递减有序的。
复杂度估算公式(master):
T(N) = aT(n/b)+O(n^d)
①当d<logb a时,时间复杂度为O(n^(logb a))
②当d=logb a时,时间复杂度为O((n^d)*logn)
③当d>logb a时,时间复杂度为O(n^d)