ソートの交換:ソートテーブル内の2つのレコードのキーコードを比較します。ソート要件に反する場合は、2つを交換します。
1.バブルソート
1.基本的な考え方:並べ替え順序を前から後ろに処理するには、隣接する要素の並べ替えコードを順番に比較し、逆の順序が見つかった場合は交換して、並べ替えコードが大きい要素が前から後ろに徐々に移動するようにします。
2.コード結果:
排序之前:
[9, -16, 21, 23, -30, -49, 21, 30, 30]
开始排序
[-16, 9, 21, -30, -49, 21, 23, 30, 30]
[-16, 9, -30, -49, 21, 21, 23, 30, 30]
[-16, -30, -49, 9, 21, 21, 23, 30, 30]
[-30, -49, -16, 9, 21, 21, 23, 30, 30]
[-49, -30, -16, 9, 21, 21, 23, 30, 30]
[-49, -30, -16, 9, 21, 21, 23, 30, 30]
排序之后:
[-49, -30, -16, 9, 21, 21, 23, 30, 30]
3.グラフィック:
4.効率分析:
元のバブリングアルゴリズムからわかるように、
ソートされる要素が正の順序である場合、1つのループのみが実行され、n-1回が比較され、移動する要素の数は0です。
ソートする要素が逆の順序である場合、n-1サイクルを実行し、(n ^ 2-n)/ 2回比較し、要素を3 *(n ^ 2-n)/ 2回移動する必要があります。
したがって、時間の複雑さはO(n ^ 2)です。移動する要素が多すぎるため、内部ソートでは遅くなります。バブルソートは要素間で順次移動するだけなので、安定したアルゴリズムです。
5.テストコード:
元のコード:
public class BubbleSort {
public static void bubbleSort(int[] data) {
System.out.println("开始排序");
int arrayLength = data.length;
for (int i = 0; i < arrayLength - 1; i++) {
for (int j = 0; j < arrayLength - 1 - i; j++) {
if (data[j] > data[j + 1]) {
int temp = data[j + 1];
data[j + 1] = data[j];
data[j] = temp;
}
}
System.out.println(java.util.Arrays.toString(data));
}
}
public static void main(String[] args) {
int[] data = { 9, -16, 21, 23, -30, -49, 21, 30, 30 };
System.out.println("排序之前:\n" + java.util.Arrays.toString(data));
bubbleSort1(data);
System.out.println("排序之后:\n" + java.util.Arrays.toString(data));
}
}
最適化1:マークを増やすj = 0とiの間に交換がない場合、マークはtrueであり、間隔シーケンスがすでに順序付けられていることを示し、不要な比較を減らし、効率を向上させます。
//优化1
public static void bubbleSort1(int[] data) {
System.out.println("开始排序");
int arrayLength = data.length;
for (int i = 0; i < arrayLength - 1; i++) {
boolean flag = false;
for (int j = 0; j < arrayLength - 1 - i; j++) {
if (data[j] > data[j + 1]) {
int temp = data[j + 1];
data[j + 1] = data[j];
data[j] = temp;
flag = true;
}
}
System.out.println(java.util.Arrays.toString(data));
if (!flag)
break;
}
}
最適化2:各サイクル交換の最後の番号の位置を記録し、位置を記録し、次回位置を取得します(位置から最後の位置までのシーケンスがすでに順序付けられているため)。
//优化2
public static void bubbleSort2(int[] data) {
System.out.println("开始排序");
int arrayLength = data.length;
int i=arrayLength-1;
int pos=0;
while(i>0) {
for (int j = 0; j <i; j++) {
if (data[j] > data[j + 1]) {
pos=j;
int temp = data[j + 1];
data[j + 1] = data[j];
data[j] = temp;
}
}
System.out.println(java.util.Arrays.toString(data));
i=pos;
}
}
他にも最適化の方法がありますが、ここでは理解と記述が簡単な方法のみを示します。
2.クイックソート(強調)(パーティション交換ソート)
これまでのすべてのインラインアルゴリズムの中で最速のものです
1.基本的な考え方:並べ替えるシーケンス内の要素(ピボットポイント、境界ポイント、通常は最初の要素とも呼ばれます)を標準として使用し、並べ替える要素を左右の2つのサブシーケンスに分割します。サブシーケンス要素のソートコードは参照要素のソートコードよりも小さく、右側のサブシーケンスのソートコードは参照要素のソートコード以上であり、2つのサブシーケンスは、各シーケンスに要素が1つだけになるまで別々に分割されます。得られたシーケンスは順序付けられたシーケンスです。
2.アイコン:
3.分割プロセス:
1.low指向待划分区域首元素,high指向待划分区域尾元素:
2.R[0]=R[low] (为了减少数据的移动将作为标准的元素暂存
到R[0]中,最后再放入最终位置)
3.high从后往前移动直到R[high].key<R[0]key;
4. R[low]=R[high], low++
5.low从前往后移动直到R[low].key>=R[0].key;
6. R[high]=R[low], high--
7. goto 3
8.直到 loW==hgh 时,R[low]=R[0](即将作为标准的元素放到
其最终位置)
概括地说,一次划分就是从表的两端交替地向中间进行扫描
将小的放到左边,大的放到右边,作为标准的元素放到中间。
4.効率分析:
5.テストコード:
public class QuickSort0 {
private static void swap(int[] data, int i, int j) {
int temp = data[i];
data[i] = data[j];
data[j] = temp;
}
private static void subSort(int[] data, int start, int end) {
if (start < end) {
int base = data[start];
int low = start;
int high = end + 1;
while (true) {
while (low < end && data[++low] - base <= 0)
;
while (high > start && data[--high] - base >= 0)
;
if (low < high) {
swap(data, low, high);
} else {
break;
}
}
swap(data, start, high);
subSort(data, start, high - 1);//递归调用
subSort(data, high + 1, end);
}
System.out.println(java.util.Arrays.toString(data));
}
public static void quickSort(int[] data){
subSort(data,0,data.length-1);
}
public static void main(String[] args) {
int[] data = { 9, -16, 30, 23, -30, -49, 25, 21, 30 };
System.out.println("排序之前:\n" + java.util.Arrays.toString(data));
System.out.println("开始排序");
quickSort(data);
System.out.println("排序之后:\n" + java.util.Arrays.toString(data));
}
}