常用的演算法有插入排序、氣泡排序、選擇排序、快速排序、歸併排序、希爾排序、堆排序、計數排序和基數排序。下面對著九種常見排序方法進行總結:
排序方法
時間複雜度
空間複雜度
個人評價
插入排序
o(n^2)
o(1)
選擇排序
氣泡排序
希爾排序
o(n log n)
快速排序
o( log n)
歸併排序
o(n)
堆排序o(1)
計數排序
o(n)
o(k)
堆排序o(n)
1.插入排序、選擇排序和氣泡排序
插入排序:將排序的記錄按照大小,插入到前面已經排好序部分的適當位置,直到整個陣列有序為止。實現的核心**為:
for (int i = 1; i < n; i++)
arr[j] = tmp;
}
選擇排序:每次遍歷陣列都會將最大(或者為最小)的元素,將其放置到陣列尾部已排好序部分的前面,尾部排好序的部分不斷增大,直到整個陣列有序為止。另一種思路是從頭部開始構建排好序的陣列。實現的核心**為:
for(int i=0; i氣泡排序:每次遍歷陣列做的操作是比較i號位置元素與i+1號元素的大小,如果i號為止的元素大於i+1號元素,那麼交換兩個的位置。這樣每次遍歷都會將"最大"的元素交換到尾部。經過n次遍歷,這個陣列就變成有序陣列了。關鍵**如下:
for (int i = 0; i < n - 1; i++)
}}
2. 希爾排序、快速排序、歸併排序和堆排序
希爾排序:排序思想**於選擇排序,選擇步長為di的元素為一組,將陣列分為di個組,每組進行插入排序。然後步長改為di/2,重複以上操作。當步長為0時結束,此時陣列就是有序的了。關鍵**如下:
while (feet > 0) else
} }feet /= 2;
}
快速排序:這是一種分治策略,首先選擇乙個元素a作為左右兩部分的分界,大於a的放在陣列的右部,小於a的放在陣列的左部分,最後將a放在「中間位置」。依照這一思想分別對左部分和右部分做同樣的操作。如此分下去,最後會得到乙個有序的陣列。
public static void process(int arr, int left, int right)
} public static int partition(int arr, int left, int right)
index++;
} return pivot;
}
歸併排序:將兩個或兩個以上的有序表合併成乙個有序表。初始時,把長度為n的陣列看成n個長度為1的有序表,然後將相鄰的有序錶兩兩合併,形成長度為2的有序表。重複以上操作,直到只剩下兩個有序表,最後合併這兩個有序錶可得到最終的排序後的陣列。關鍵**如下:
public static void process(int arr, int left, int right)
int mid = (left + right) / 2;
process(arr, left, mid);
process(arr, mid + 1, right);
merge(arr, left, mid, right);
}public static void merge(int arr, int left, int mid, int right) else
}while (l <= mid)
while (r <= right)
for (int i = 0; i < help.length; i++)
}
堆排序:陣列形式的完全二叉樹。針對大根堆,每個節點的父節點的值大於任意乙個子節點的值。這樣我們就可以得到這個陣列的最大值,然後將該最大值放在陣列尾部排好序的部分,縮小大根堆的範圍,根據這個原理,最後就可以得到乙個有序的陣列。
public int heapsort(int a, int n)
for (int i = n - 1; i > 0; i--)
return a;
} void heapadjust(int a, int index, int length)
if (temp > a[childleft]) else
} a[index] = temp;
}
3.計數排序和基數排序
計數排序:針對陣列arr,得到這個陣列的最大值max和最小值min,然後設定乙個陣列a(長度為max-min+1),a中i處元素代表min+i這個數出現的次數,遍歷一遍陣列arr後我們就可以填滿a。最後只要遍歷一遍陣列a,就會得到乙個排序後的陣列了。
int min = arr[0];
int max = arr[0];
for (int i = 1; i < arr.length; i++)
int countarr = new int[max - min + 1];
for (int i = 0; i < arr.length; i++)
int index = 0;
for (int i = 0; i < countarr.length; i++)
}
基數排序:
按照先按照每個數的個位進行排序合併成陣列,然後再按照十位進行排序後合併陣列,然後百位、千位.....直到得到有序陣列。這裡也用到了桶排序的概念。
public static void radixsort(int arr)
radixsortforpositive(negarr);
radixsortforpositive(posarr);
int index = 0;
for (int i = negarr.length - 1; i >= 0; i--) arr[index++] = -negarr[i];
for (int i = 0; i < posarr.length; i++) arr[index++] = posarr[i];
}
public static void radixsortforpositive(int arr)
for (int i = 0; i < arr.length; i++)
long base = 10;
while (base <= integer.max_value)
}arraylist> tmp = qarr1;
qarr1 = qarr2;
qarr2 = tmp;
base *= 10;
} int index = 0;
for (int i = 0; i < 10; i++)
} }
資料結構 排序演算法總結
1 二路歸併排序 二路歸併排序 思路 利用分治思想,對原陣列進行二分分段,使元素在每一小段內有序,然後逐漸合併 如,最小分段是2,先2內有序,合併為4,4內有序。時間複雜度 o nlogn 空間複雜度 o n 需要乙個額外的陣列作為臨時儲存 static void mergesort int arr...
資料結構 排序演算法總結
def bubblesort array flag false length len array for i in range length for j in range length i 1 if array j array j 1 temp array j array j array j 1 a...
資料結構 排序演算法總結
1.排序 所謂排序,就是使一串記錄,按照其中的某個或某些關鍵字的大小,遞增或遞減的排列起來的操作。2.穩定性 假定在待排序的記錄序列中,存在多個具有相同的關鍵字的記錄,若經過排序,這些記錄的相對次序保持不變,即在原序列中,r i r j 且r i 在r j 之前,而在排序後的序列中,r i 仍在r ...