幾種內部排序演算法
阿新 • • 發佈:2019-02-10
通常說的排序指:
①.內部排序演算法(資料在記憶體中進行排序)
②.外部排序演算法(資料大,需要訪問外存)
我們把排序進行了劃分,並計算出排序的時間複雜度,穩定性;下來逐個對排序演算法實現,並歸納出排序的實現過程和思想。
插入類排序
插入類排序的思想:在一個已經排好序的有序序列內,對待排序的無序序列區中記錄逐個進行處理,每一步將一個待排序的記錄與同組那些已經排好序的記錄進行比較,然後有序的插到該有序序列區中,直到將所有待排記錄全部插入為止。(類似於打撲克牌)
- 直接插入排序
#include<stdio.h>
int insertsort(int *L);
int main(void){
int i;
int L[10] = {2,99,88,54,23,76,34,13,4,5};
insertsort(L);
for(i = 0;i < 10;i++)
printf("%d ",L[i]);
return 0;
}
int insertsort(int *L){
int i,j;
int K; //用於儲存待插入的資料
for(i = 1;i < 10;i++){ // 10個數據比較9次就行了
K = L[i]; //將待插入資料備份到 K 中
for (j = i-1;L[j] > K;j--) //從後往前比較
L[j+1] = L[j]; //把大於 K 的都向後移一個位置
L[j+1] = K; //將 K 放到正確位置
}
return *L;
}
可將待排序的陣列分為兩部分
[已排序區][待排序區]
[2][99,88,54,23,76,34,13,4,5]
然後依次在待排序區取出一個數據,與排序區比較,比待排資料大的,依次往後移一位,否則,這個位置就是要插入資料的位置。
- 希爾排序
package insertsort;
/**
*
* @author Administrator
* (Shell's Sort)是插入排序的一種又稱“縮小增量排序”(Diminshing Increment Sort)
* 是直接插入排序演算法的一種更高效的改進版本。
* 希爾排序是非穩定排序演算法。時間複雜度為
* 該方法因D.L.Shell於1959年提出而得名。
* 基本思想:
* 先取一個小於n的整數d1作為第一個增量,把檔案的全部記錄分組。所有距離為d1的倍數的記錄放在同一個組中。
* 先在各組內進行直接插入排序;然後,取第二個增量d2<d1重複上述的分組和排序,直至所取的增量 =1( < …<d2<d1),
* 即所有記錄放在同一組中進行直接插入排序為止。
* 時間複雜度:O(n2)
*/
public class sortShell {
public static int[] shellSort(int[] array) {
int d=array.length; //增量
while(true){
d=d/2;
for(int x=0;x < d;x++){
for(int i=x+d;i<array.length;i=i+d){ //各組內進行直接插入排序
int temp=array[i];
int j;
for(j=i-d;j>=0&&array[j]>temp;j=j-d){
array[j+d]=array[j];
}
array[j+d]=temp;
}
}
if(d==1){
break;
}
}
return array;
}
}
交換類排序
- 氣泡排序
package swapsort;
public class sortBubble {
/**
* 氣泡排序
* 比較相鄰的元素。如果第一個比第二個大,就交換他們兩個。
* 對每一對相鄰元素作同樣的工作,從開始第一對到結尾的最後一對。在這一點,最後的元素應該會是最大的數。
* 針對所有的元素重複以上的步驟,除了最後一個。
* 持續每次對越來越少的元素重複上面的步驟,直到沒有任何一對數字需要比較。
* @param numbers 需要排序的整型陣列
* 時間複雜度:O(n2)
*/
public static int[] bubbleSort(int[] array2) {
int temp = 0;
for(int i = 0;i < array2.length;i++){
for(int j = 0;j < array2.length- i -1;j++){
if(array2[j] > array2[j+1]){
temp = array2[j];
array2[j] = array2[j+1];
array2[j+1] = temp;
}
}
}
return array2;
}
}
- 快速排序
package swapsort;
/**
* 儘管快速排序的最壞時間為O(n2)
* 但就平均效能而言,它是基於關鍵字比較的內部排序演算法中速度最快者,快速排序亦因此而得名。
* 它的平均時間複雜度為O(nlgn)
* @author Administrator
* 時間複雜度:O(nlogn)--O(n2)
*/
public class sortQuit {
public static int[] quitSort(int[] array) {
if(array.length > 0){
quitRecursion(array,0,array.length-1);
}
return array;
}
//分治思想的體現,遞迴實現 Recursion:遞迴
private static void quitRecursion(int[] array, int low, int high) {
if(low < high){
int middle = getMiddle(array,low,high);
quitRecursion(array,low,middle-1);
quitRecursion(array,middle+1,high);
}
}
private static int getMiddle(int[] array, int low, int high) {
int middle = array[low]; //選一個數作為中軸
while(low < high){
while(low < high && array[high] >= middle){
high--;
}
array[low] = array[high]; //比中軸小的,放到低端
while(low < high && array[low] <= middle){
low++;
}
array[high] = array[low]; //比中軸大的,放到高階
}
array[low] = middle; // 中軸記錄到位
return low; //返回中軸位置
}
}
選擇類排序
- 簡單選擇排序
package selectsort;
/**
*
* @author Administrator
* 演算法思想:遍歷整個陣列找出最小的數,如果不是第一個數則與第一個數交換,否則不變。
* 第二趟從剩餘的數中,找出最小的數,重複上述操作,依次完成整個陣列的排序
* 時間複雜度O(n2)
*/
public class sortSimple {
public static int[] simpleSort(int[] array) {
int temp = 0;
int index = 0;
int minNumIndex = 0;//存最小的數的下標
for(int i = 0;i < array.length-1;i++){
minNumIndex = i;
temp = 0;
for(int j = i+1;j < array.length;j++){
if( array[minNumIndex] > array[j] ){
minNumIndex = j;
}
}
temp = array[minNumIndex];
array[minNumIndex] = array[i];
array[i] = temp;
}
return array;
}
}