冒泡排序
package com.test;
/**
* 冒泡排序
*
* 時間複雜度爲:o(n`2) 空間複雜度爲o(1)
*
* 最好最壞複雜度都是o(n`2)
*
* 說明:
* 對當前還未排序的所有數,自上而下對相鄰的兩個數依次進行比較和調整,
* 讓較大的數日後面移動 , 讓較小的數往前面移動
*
* 算法比較穩定 爲兩兩比較 不存在跳躍
*
* Created by abing on 2015/11/26.
*/
public class SuanFaBubble {
public static void main(String[] args){
int[] a = {1,2,6,5,4,3,23,43,123,432};
sort(a);
}
public static void sort(int[] arr){
int tmp = 0;
for ( int i = 0 ; i < arr.length - 1 ; i++ ){
for (int j = 0 ; j < arr.length - 1 - i ; j++){
if (arr[j] > arr[j+1]){
tmp = arr[j];
arr[j] = arr[j+1];
arr[j+1] = tmp;
}
}
}
for (int a : arr){
System.out.print(a + " ");
}
}
}
基數排序
package com.test;
import java.util.ArrayList;
import java.util.List;
/**
* 基數排序
*
* 時間複雜度爲o(n+k)
* 最好最壞都同樣
*
* 說明:
* 將全部待比較數值(正整數)統一爲一樣的數位長度,數位較短的數前面補零。
* 而後,從最低位開始,依次進行一次排序。
* 這樣從最低位排序一直到最高位排序完成之後,數列就變成一個有序序列
*
* Created by abing on 2015/11/26.
*/
public class SuanFaCount {
public static void main(String[] args){
int[] array ={1,3,6,2,5,87,54,32,21,22,33,44,11};
sort(array);
for (int a : array){
System.out.print(a + " ");
}
}
public static void sort(int[] array){
//首先肯定排序的趟數;
int max=array[0];
for(int i=1;i<array.length;i++){
if(array[i]>max){
max=array[i];
}
}
int time=0;
//判斷位數;
while(max>0){
max/=10;
time++;
}
//創建10個隊列;
List<ArrayList> queue=new ArrayList<ArrayList>();
for(int i=0;i<10;i++){
ArrayList<Integer>queue1=new ArrayList<Integer>();
queue.add(queue1);
}
//進行time次分配和收集;
for(int i=0;i<time;i++){
//分配數組元素;
for(int j=0;j<array.length;j++){
//獲得數字的第time+1位數;
int x=array[j]%(int)Math.pow(10,i+1)/(int)Math.pow(10, i);
ArrayList<Integer>queue2=queue.get(x);
queue2.add(array[j]);
queue.set(x, queue2);
}
int count=0;//元素計數器;
//收集隊列元素;
for(int k=0;k<10;k++){
while(queue.get(k).size()>0){
ArrayList<Integer>queue3=queue.get(k);
array[count]=queue3.get(0);
queue3.remove(0);
count++;
}
}
}
}
}
快速排序
package com.test;
/**
* 快速排序
*
* 時間複雜度爲o(nlogn) 空間複雜度爲o(logn)
*
* 最壞O(n^2) 當劃分不均勻時候 逆序and排好序都是最壞狀況
最好O(n) 當劃分均勻
partition的時間複雜度: O(n)一共須要logn次partition
*
*說明:
* 選擇一個基準元素,一般選擇第一個元素或者最後一個元素,經過一趟掃描,將待排序列分紅兩部分,
* 一部分比基準元素小,一部分大於等於基準元素,此時基準元素在其排好序後的正確位置,而後再用一樣的方法遞歸地排序劃分的兩部分。
*
* Created by abing on 2015/11/26.
*/
public class SuanFaFast {
public static void main(String[] args){
int[] aa = {1,4,6,2,5,8,21,43,22,44,33};
quick(aa);
for (int a : aa){
System.out.print(a + " ");
}
}
public static void quick(int[] arr){
if (arr.length > 0){
quickSort(arr , 0 ,arr.length - 1);
}
}
public static void quickSort(int[] arr , int low , int high){
if (low < high){
int middle = getMiddle(arr , low ,high); //將list一份爲二
quickSort(arr , low , middle - 1); //對低字表進行遞歸排序
quickSort(arr , middle + 1 , high); //對高字表進行遞歸排序
}
}
public static int getMiddle(int[] arr , int low , int high){
int tmp = arr[low]; //數組的第一個做爲中軸
while (low < high){
while (low < high && arr[high] >= tmp){
high--;
}
arr[low] = arr[high]; //比中軸小的記錄移到低端
while (low < high && arr[low] <= tmp){
low++;
}
arr[high] = arr[low]; //比中軸大的記錄移到高端
}
arr[low] = tmp; //中軸記錄到尾
return low; //返回中軸記錄
}
}
希爾排序
package com.test;
/**
* 希爾排序
*
* 時間複雜度o(n`1.2)
*
* 說明:
* 算法先將要排序的一組數按照某個增量d(n/2 , m爲要排序的個數)分爲若干組 , 每組中記錄的下標相差d,
* 對每組中所有元素進行直接插入排序。而後再用一個較小的增量(d/2)對它進行分組,在每組中再進行插入排序。
* 當增量減小到1的時候,進行直接插入排序後。排序完成。
*
*
* Created by abing on 2015/11/26.
*/
public class SuanFaHill {
public static void main(String[] args){
int[] arr = {1,8,4,2,6,12,34,21,33,55,11,88,33};
sort(arr);
}
public static void sort(int[] arr){
double d1 = arr.length;
int tmp = 0 ;
while (true) {
d1 = Math.ceil(d1/2);
int d = (int) d1;
for (int x = 0 ; x < d ; x++){
for (int i = x+d ; i < arr.length ; i+=d){
int j = i -d;
tmp = arr[i];
while (j >=0 && tmp <arr[j]){
arr[j+d] = arr[j];
j -=d;
}
arr[j+d] = tmp;
}
}
if (d == 1){
break;
}
}
for (int a : arr){
System.out.print(a + " ");
}
}
}
插入排序
package com.test;
/**
* 插入排序
* 時間複雜度 o(n`2) 控件複雜度 o(1)
*
* 最好爲n 最壞複雜度爲n`2
*
* 說明:
* 從頭開始排序 若是後面有比前面小的直接插入其中
*
* Created by abing on 2015/11/26.
*/
public class SuanFaInsert {
public static void main(String[] args){
int[] a = {1,2,6,5,4,3,23,43,123,432};
sortWhile(a);
}
/**
* 這一種使用的是兩層for循環進行排序
* @param arr
*/
public static void sort(int[] arr){
int tmp = 0;
for (int i = 0 ; i < arr.length ; i++) {
for (int j = i-1 ; j >= 0 ; j--){
if (arr[j+1] < arr[j]){
tmp = arr[j+1];
arr[j+1] = arr[j];
arr[j] = tmp;
}
}
}
for (int a : arr){
System.out.print(a + " ");
}
}
/**
* 本循環與上面的差很少 只不過是使用了while循環
* @param arr
*/
public static void sortWhile(int[] arr){
int tmp = 0;
for (int i = 1 ; i < arr.length ; i++) {
int j = i-1;
while (arr[j+1] < arr[j]){
tmp = arr[j+1];
arr[j+1] = arr[j];
arr[j] = tmp;
j--;
}
}
for (int a : arr){
System.out.print(a + " ");
}
}
}
歸併排序
package com.test;
import java.util.Arrays;
/**
* 歸併排序
*
* 時間複雜度爲o(nlogn) 空間複雜度爲 o(n) + o(logn)
*
* 說明:
* 把兩個(或者兩個以上)的有序表合併成一個新的有序表 , 把待排序序列分爲若干個序列 , 每一個子序列都是有序的
* 而後再把有序的子序列合併爲總體有序序列
*
* Created by abing on 2015/11/26.
*/
public class SuanFaMerge {
public static void main(String[] args){
int[] data = {1,2,3,5,21,43,65,87,22,33,44,55,99};
sort(data , 0 , data.length-1);
}
public static void sort(int[] data , int left , int right){
if (left < right){
int center = (right + left)/2;
System.out.println("11 : "+left + " " + center + " " + right);
sort(data, left, center);
System.out.println("22 : "+left + " " + center + " " + right);
sort(data, center + 1, right);
System.out.println("33 : "+left + " " + center + " " + right);
merge(data , left ,center , right);
}
}
public static void merge(int[] data , int left , int center , int right){
// System.out.println(left + " " + center + " " + right);
int[] tmpArr = new int[data.length];
int mid = center+1;
//記錄中間數組的索引
int third = left;
int tmp = left;
while (left <= center && mid <= right){
//從兩個數組中取出最小的放入中間數組
if (data[left] <= data[mid]){
tmpArr[third++] = data[left++];
}else {
tmpArr[third++] = data[mid++];
}
}
//剩餘部分依次放入中間數組
while (mid <= right){
tmpArr[third++] = data[mid++];
}
while (left <= center){
tmpArr[third++] = data[left++];
}
//將中間數組中的內容複製回原數組
while (tmp <= right){
data[tmp] = tmpArr[tmp++];
}
System.out.println(Arrays.toString(data));
}
}
選擇排序
package com.test;
/**
* 選擇排序 時間複雜度爲o(n`2) 空間複雜度爲o(1)
*
* 沒有最好最壞的狀況 排序時間都是同樣的
*
* 說明:
* 從頭開始排序 從後面選擇最小的與第一個交換 而後再從後面選擇最小的與第二個進行交互
*
* 知道交換到倒數第二個與倒數第一個進行交換
*
* Created by abing on 2015/11/26.
*/
public class SuanFaSelect {
public static void main(String[] args){
int[] arr ={1,4,7,3,22,65,44,22,88,54,76,31,32};
sort(arr);
}
public static void sort(int[] arr){
for (int i = 0 ; i < arr.length -1 ; i++){
int min = i;
int tmp;
for (int j = i+1 ; j < arr.length ; j++){
if (arr[j] < arr[min]){
min = j;
}
}
if (min != i){
tmp = arr[min];
arr[min] = arr[i];
arr[i] = tmp;
}
}
for (int a : arr){
System.out.print(a + " ");
}
}
}
堆排序
package com.test;
import java.util.Arrays;
/**
* 堆排序
*
* 時間複雜度o(nlogn) 空間複雜度o(1)
*
* 沒有最好與最壞的區別 時間複雜度都是o(nlogn) 不是很穩定的算法
*
* 說明:
*具備n個元素的序列(h1,h2,...,hn),當且僅當知足(hi>=h2i,hi>=2i+1)或(hi<=h2i,hi<=2i+1)(i=1,2,...,n/2)時稱之爲堆。
* 在這裏只討論知足前者條件的堆。由堆的定義能夠看出,堆頂元素(即第一個元素)必爲最大項(大頂堆)。徹底二叉樹能夠很直觀地表示堆的結構。
* 堆頂爲根,其它爲左子樹、右子樹。初始時把要排序的數的序列看做是一棵順序存儲的二叉樹,調整它們的存儲序,使之成爲一個堆,
* 這時堆的根節點的數最大。而後將根節點與堆的最後一個節點交換。而後對前面(n-1)個數從新調整使之成爲堆。
* 依此類推,直到只有兩個節點的堆,並對它們做交換,最後獲得有n個節點的有序序列。
* 從算法描述來看,堆排序須要兩個過程,一是創建堆,二是堆頂與堆的最後一個元素交換位置。
* 因此堆排序有兩個函數組成。一是建堆的滲透函數,二是反覆調用滲透函數實現排序的函數。
*
*
* 對於大數據的處理呢,若是對100億條數據選擇Topk數據,選擇快速排序好仍是堆排序好?
* 答案是隻能用堆排序。
* 堆排序只須要維護一個k大小的空間,即在內存開闢k大小的空間。而快速排序須要開闢能存儲100億條數據的空間
*
* Created by abing on 2015/11/26.
*/
public class SuanFaStack {
public static void main(String[] args){
int[] a = {3,1,4,6,2,43,21,65,22,44,88,11};
headSort(a);
for (int i : a){
System.out.print(i + " ");
}
}
public static void headSort(int[] arr){
int arrlength = arr.length;
for (int i = 0 ; i < arrlength - 1 ; i++){
buildMaxHeap(arr, arrlength - 1 - i);
swap(arr, 0, arrlength - 1 - i);
System.out.println(Arrays.toString(arr));
}
}
public static void swap(int[] arr , int i , int j){
int tmp = arr[i];
arr[i] = arr[j];
arr[j] = tmp;
}
public static void buildMaxHeap(int[] data , int lastIndex){
for (int i = (lastIndex-1)/2 ; i >= 0 ; i--){
int k = i;
while (k*2 + 1 <= lastIndex){
int biggerIndex = 2*k + 1;
if (biggerIndex < lastIndex){
if (data[biggerIndex] < data[biggerIndex+1]){
biggerIndex++;
}
}
if (data[k] < data[biggerIndex]){
swap(data , k , biggerIndex);
k = biggerIndex;
}else {
break;
}
}
}
}
}