Java資料結構:排序演算法(氣泡排序,選擇排序,插入排序,希爾排序,快速排序,堆排序和合並排序)
阿新 • • 發佈:2019-02-03
public class 氣泡排序 { public static void main(String[] args) { int a[] = { 1, 9, 6, 8, 5, 65, 65, 84, 1, 2, 5, 23, 7, 889 }; for (int i = 0; i < a.length - 1; i++) { //使用兩個for迴圈遍歷 for (int j = 0; j < a.length - i - 1; j++) { //減i是為了防止輸出已經比較好的 if (a[j] > a[j + 1]) { //如果前面的數大於後面的數,則進行交換 int temp = a[j]; a[j] = a[j + 1]; a[j + 1] = temp; } } } System.out.println(Arrays.toString(a)); } }
氣泡排序:基本思想:對比相鄰的元素值,如果滿足條件就交換元素值,把比較小的元素移動到陣列前面,把比較大的移動到陣列後面。
public class 選擇排序 { public static void main(String[] args) { int array[] = { 63, 4, 24, 1, 3, 15 }; int index; for (int i = 1; i < array.length; i++) { index = 0; for (int j = 1; j <= array.length - i; j++) { //迴圈 if (array[j] > array[index]) { index = j; //獲取一個迴圈內最大元素 } } int temp = array[array.length - i]; //將最大元素放到陣列最後面 array[array.length - i] = array[index]; array[index] = temp; } System.out.println(Arrays.toString(array)); } }
選擇排序基本思想:將指定排序位置與其他陣列元素分別對比,如果滿足條件就交換元素值,這裡不是交換元素值,而是把滿足條件的元素與指定位置的排序位置交換。
public class 插入排序 { public static void main(String[] args) { int[] array = { 56, 5, 185, 56, 8, 646, 589, 63, 846, 351656, 6516, 654465 }; int i, j, t; for (i = 1; i < array.length; i++) { t = array[i]; j = i - 1; while (j >= 0 && t < array[j]) { array[j + 1] = array[j]; j--; } array[j + 1] = t; } for (int q = 0; q < array.length; q++) { System.out.print(array[q] + " "); } } }
插入排序基本思想:先從陣列中取出前兩個資料,比較。在依次取出一個,與前兩個比較比某個數大的放右邊,比其小的放左邊
public class Shell排序 {
public static void main(String[] args) {
int array[] = { 1, 5, 85, 416, 74, 123, 68, 46, 4, 68, 4, 61 };
int j, temp;
for (int r = array.length / 2; r >= 1; r /= 2) {
for (int i = r; i < array.length; i++) {
temp = array[i];
j = i - r;
while (j >= 0 && temp < array[j]) {
array[j + r] = array[j];
j -= r;
}
array[j + r] = temp;
}
}
for (int i = 0; i < array.length; i++) {
System.out.print(array[i] + " ");
}
}
}
Shell排序的基本思想:將n個元素分成n/2個數字序列,第1個和第n/2+1個數據為一對,每次迴圈使每個序列排號,再變成n/4個,再次排序。多次重複,直到序列減少到最後變成一個。
import java.util.Arrays;
public class 快速排序 {
public static void main(String[] args) {
int[] s = { 1, 5, 69, 5, 45, 1, 21, 23, 65, 9, 89, 87 };
quickSort(s,0,s.length-1);
System.out.println(Arrays.toString(s));
}
public static void quickSort(int[] s, int left, int right) {
int f, t;
int rtemp, ltemp;
ltemp = left;
rtemp = right;
f = s[(left + right) / 2];
while (ltemp < rtemp) { //左邊的指標小於右邊的指標
while (s[ltemp] < f) { //從左邊開始找到比中間值大的指標
++ltemp;
}
while (s[rtemp] > f) { //從右邊開始找到比中間值小的指標
--rtemp;
}
if (ltemp <= rtemp) { //如果右邊開始的指標大於左邊開始的指標,但左邊的值大於右邊,交換兩處的值
t = s[ltemp];
s[ltemp] = s[rtemp];
s[rtemp] = t;
--rtemp; //向左運動
++ltemp; //向右運動
}
}
if (ltemp == rtemp) { //如果二者運動後在同一指標,左邊指標後移
ltemp++;
}
if (left < rtemp) { //如果右邊指標沒有遍歷到最左邊,遞迴
quickSort(s, left, ltemp - 1);
}
if (ltemp < right) { //如果左邊指標沒有遍歷到右邊,遞迴
quickSort(s, rtemp + 1, right);
}
}
}
快排思想:設定一個分界值,通過該分界值將陣列分成左右兩部分,左邊都小於分界值,右邊都大於分界值
在遞迴左邊,右邊
import java.util.Arrays;
public class 堆排序 {
public static void main(String[] args) {
int a[] = { 1, 56, 9, 5, 6, 23, 21, 5, 62, 66 };
int n = 10;
int i, j, k;
int t;
for (i = n / 2 - 1; i >= 0; i--) {
while (2 * i + 1 < n) { //對樹兩邊分開比較排序
j = 2 * i + 1; //做到右樹葉比左樹頁大
if ((j + 1) < n) { if (a[j] < a[j + 1]) { //此處為了防止出現類似於10個結點的樹的樹葉情況 j++;
}
}
if (a[i] < a[j]) { //如果左樹葉大於右樹葉,交換
t = a[i];
a[i] = a[j];
a[j] = t;
i = j;
} else {
break;
}
}
}
for (i = n - 1; i > 0; i--) { //不在分開排序,總體排序
t = a[0]; //由下向上
a[0] = a[i];
a[i] = t;
k = 0;
while (2 * k + 1 < i) {
j = 2 * k + 1;
if ((j + 1) < i) {
if (a[j] < a[j + 1]) { //此處為了防止出現類似於10個結點的樹的樹葉情況
j++;
}
}
if (a[k] < a[j]) { //如果下面的大於上面的,交換二者
t = a[k];
a[k] = a[j];
a[j] = t;
k = j;
} else {
break;
}
}
}
System.out.println(Arrays.toString(a));
}
}
堆排序思想:先將樹分成兩部分,左右,每一級由左到右,遞增,(在同一節點下);其次在在整個樹中,從下往上排序,每次取出最上面的樹排在最後,遞迴下去,即可排序。
import java.util.Arrays;
public class 合併排序 {
public static void main(String[] args) {
int s[] = { 5, 45, 6, 5, 2, 3, 23, 6, 65, 56, 98, 9, 7, 45, 4, 52 };
mergeSort(s, s.length);
System.out.println(Arrays.toString(s));
}
static void mergeOne(int a[], int b[], int n, int len) {
int i, j, k, s, e;
s = 0;
while (s + len < n) { //迴圈
e = s + 2 * len - 1;
if (e >= n) {
e = n - 1;
}
k = s;
i = s;
j = s + len;
while (i < s + len && j <= e) { //合併並排序
if (a[i] <= a[j]) { //兩個陣列第一位誰小誰先排,未排的元素等下次再次比較
b[k++] = a[i++];
} else {
b[k++] = a[j++];
}
}
while (i < s + len) {
b[k++] = a[i++];
}
while (j <= e) {
b[k++] = a[j++];
}
s = e + 1;
}
if (s < n) {
for (; s < n; s++) {
b[s] = a[s];
}
}
}
static void mergeSort(int a[], int n) { //開始排序
int h, len, f;
len = 1;
f = 0;
int p[] = new int[n];
while (len < n) { //排序次數
if (f == 1) { //互相交換排序
mergeOne(p, a, n, len);
} else {
mergeOne(a, p, n, len);
}
len = len * 2; //每次排序合併兩個陣列
f = 1 - f; //改變f的值
}
if (f == 1) { //解決只有一個數的陣列
for (h = 0; h < n; h++) {
a[h] = p[h];
}
}
}
}
合併排序思想:將1個數組分成n個元素,相鄰兩項比較併合並,依次2和2比較併合並。。。。。