要求:掌握演算法思想,效能分析,**實現
注:本文預設遞增排序
一,排序的基本概念
1,什麼是排序:將乙個沒有順序的數列進行重新排列是它成為乙個遞增(遞減)序列
2,穩定性:如果數列中有兩個元素的值是相等的,排序後他們的相對位置沒有發生改變,就認為該排序演算法穩定。
3,內部排序:指排序期間元素全部存放在記憶體中的排序
外部排序:排序期間元素無法全部同時存放在記憶體中,必須在排序過程中根據要求不斷在內,外存之間進行移動
插入排序:每次將乙個待排序的序列插入到乙個前面已經排好的子串行中
設已知數列[ a1 a2,,,ai,,,,an],已知a1,,,ai已經是遞增序列了,如何將ai+1號元素插入到a1,,,ai中使得,它們任然是有序序列
思想:
**實現:
void insertsort(int a,int n)
for(j=i-1;j>=high+1;j--)//向後移動元素
a[j+1]=a[j];
a[high+1]=a[0];//插入元素
}}
效能分析:
思想:先將排序表分割成d個形如 [i,i+d,i+2d,i+3d,,,,i+kd]的特殊子表,分別進行直接插入排序,當整個表中元素已經基本有序時,再對全體記錄進行一次直接插入排序。
**實現:
void shellsort(int a,int n)
if(flag==false)
return;//是遞增序列,結束迴圈
} }for(int k=0;k效能分析:
思想:在排序表【1,,,n】中任取乙個元素pivot作為基準,通過一趟排序將待排序表劃分為兩個部分,pivot前面的元素均小於它,後面的元素均大於它。所以一次劃分會讓當前的pivot元素歸位,進行對已經劃分的部分進行相同操作,知道每乙個元素歸位。
一次劃分實現思路:
**實現:
int partition(int a,int low,int high)
} a[0]=a[k]; }
void buildmaxheap(int a,int len)
}void heapsort(int a,int len)
for(int k=0;k0&&a[i]效能分析:
思想:將相鄰的兩組序列進行有序的歸併。開始時乙個元素為一組,n個元素為n組,然後將相鄰i號元素和i+1號元素歸併成有序序列,就出現n/2組,繼續對他們進行歸併出現n/4組,,,,直到歸為一組為止。
**實現:
(**有問題)
void merge(int a,int low,int mid,int high);
sort1(a);
system.out.println("====》直接插入排序");
sort2(a);
system.out.println("====》折半插入排序");
sort3(a);
system.out.println("====》希爾排序");
sort4(a);
system.out.println("====》選擇排序");
sort5(a);
system.out.println("====》堆排序");
sort6(a);
system.out.println("====》氣泡排序");
// sort7(a,0,a.length-1);
// show(a);
// system.out.println("====》快速排序");
sort8(a,0,a.length-1);
show(a);
system.out.println("====》歸併排序");
}/**
* 方法:直接插入排序
* 思想:
* 預設第乙個元素是有序列表。
* 記錄要排序的元素temp=a[i]
* 從第二個元素開始,和順序表中的元素進行比較,找到可以插入元素的位置。
* 把有序列表中大於temp的元素後移乙個位置,空出插入的位置
* 插入元素
*/static void sort1(int a)
a[j+1] = temp; //插入,此處的arr[j+1]其實是上邊的「arr[j]」,執行了乙個j--操作
}show(a);
}/**
* 方法:折半插入
* 思想:
* 記錄要插入的元素temp=a[i]
* 對前面有序列表折半查詢可以插入的位置,
* 將有序列表中比temp大的元素後移一位,流出乙個空間插入temp元素
*/public static void sort2(int a)
//將a[low]--a[i-1]的數都想後移一位,插入元素的位置空出來
for (int j = i; j > low; j--)
a[low] = temp; //最後將a[i]插入a[low]
}show(a);
}/**
* 方法:希爾排序
* 思想:
* i從0+d開始,因為分組後的第一組是0,d,2d,3d...這樣乙個序列.所以直接從d開始比較
* 此迴圈比較演算法區別:假設有乙個16項陣列,下標為0~15,當d=5時,分為5組
* 以下標表示:(0,5,10,15),(1,6,11),(2,7,12),(3,8,13),(4,9,14)
* 如果分別針對每一組插入排序,則下標控制很複雜,所以外層for迴圈每次對每一分組的前2個資料排序
* 然後前3個,然後前4個...這和組數有關
* 即當i=5時,對(0,5,10,15)中的(0,5)排序
* i=6時,對(1,6,11)中的(1,6)排序.....
* i=10時,對(0,5,10,15)中的(0,5,10)排序......
* 一直到d=1時,此時的陣列基本有序,資料項移動次數大大減少
* */
public static void sort3(int a)
a[j] = temp;
}d = d / 2;
}show(a);
}/**
* 選擇排序,每次從後面無序列表中選出最小值插入前方有序列表
* @param a
*/public static void sort4(int a)
}if (k != i)
}show(a);
}/**
* 堆排序
* @param a
*/public static void sort5(int a) }}
show(a);
}/**
* 氣泡排序
* @param a
*/public static void sort6(int a) }}
show(a);
}/**
* 快速排序
* @param a
* @param low
* @param high
* @return
*/public static int sort7(int a, int low, int high)
return a;
}public static int getmiddle(int a,int low, int high)
a[low] = a[high];
//從左往右找比基準大的元素並交換
while (lowa[high] = a[low];
}a[low] =temp;
return low;
}/**
* 歸併排序
*/public static int sort8(int a,int left,int right)
return a;
}private static void merge(int a, int left, int middle, int right)else
}//剩餘部分以此放入臨時陣列。以下兩個while只會執行其中乙個
while (left<=middle)
while (rightindex<=right)
//將臨時陣列中的內容拷貝回原陣列
while (tmp<=right)
}public static void show(int a)
}}
資料結構與演算法 堆排序演算法回顧
堆排序是利用堆這種資料結構而設計的一種排序演算法,堆排序是一種選擇排序,它的最壞,最好,平均時間複雜度均為o nlogn 它也是不穩定排序。堆排序的應用場景主要有 topk問題,優先順序佇列等。原理 1.將存放在array 0,n 1 中的n個元素建成初始堆 2.此時,堆頂元素該堆的最大值 3.將堆...
資料結構 樹的回顧
度 結點擁有的子樹數就稱為結點的度。度為0的結點稱為葉子結點或終端結點。度不為0的結點稱為非終端結點或分支結點。樹的度為樹內各結點度的最大值。樹的層次 結點的層次從根開始定義起,根為第一層,根的孩子為第二層。若某結點在第l層,則其子樹的根就在l 1層。樹的高度 樹中結點的最大層次稱為樹的深度或高度。...
回顧資料結構 鍊錶
鍊錶真不是個東西 附上靈魂畫圖一張 private node dummyhead 虛擬頭節點 int size 無參建立鍊錶 public linkedlist 建立鍊錶,並將陣列放到鍊錶上 public linkedlist e e 獲得鍊錶長度 public int getsize 判斷是否為空...