9 つの基本的な並べ替えアルゴリズム

カテゴリの並べ替えの概要

ここに画像の説明を挿入

時空間の複雑さの概要

ここに画像の説明を挿入
以下の並べ替え方法はすべて、小さいものから大きいものの順に並べ替えられています。

1.1. 直接挿入ソート

アルゴリズム思考
    1.从位置1的数值n开始,将前面已经遍历过的数值集合看成数组m,则将n往m中插入
    2.n插入到集合m中时从后往前比较,如果比n大则往后移一位,如果比较到比n小,则当前位置就是插入n的位置
    3.通过1、2的操作则可以保证每次插入n后m的集合都是排好的序列
    4.循环1、2、3操作将集合中所有数值均插入一遍即排序完成
コード
private int[] array = {
    
    23, 11, 7, 29, 33, 59, 8, 20, 9, 3, 2, 6, 10, 44, 83, 28, 5, 1, 0, 36};

/**
 * 直接插入排序:从1开始遍历数组,每个数字都在前面已经遍历的数字中插入
 * 从小到大排序的话碰到比它大的则往后移,直到比它小为止
 */
private void insertSort() {
    
    
    for (int i = 1; i < array.length; i++) {
    
    
        int temp = array[i];
        int j;
        // 在前面已经遍历过的数字中比较若小于则往后移
        for (j = i - 1; j >= 0; j--) {
    
    
            if (temp < array[j]) {
    
    
                array[j + 1] = array[j];
            } else {
    
    
                break;
            }
        }
        array[j + 1] = temp;
    }
}

kotlin言語の実装

class Solution {
    fun sortArray(nums: IntArray): IntArray {
        if (null == nums || nums.size == 0) {
            return nums
        }

        for (i in 1 until nums.size) {
            val temp = nums[i]
            for (j: Int in i - 1 downTo 0) {
                if (temp < nums[j]) {
                    nums[j + 1] = nums[j]
                    nums[j] = temp
                } else {

                    break
                }

            }
        }
        return nums
    }
}

1.2. バイナリソート

アルゴリズム思考

1. 位置 1 からの値を n とし、以前に走査した値セットを配列 m とみなし、m に n を代入します。
2. 集合 m に n を代入する場合は、二分法を使用し、まず m の中央の値を比較し、n より大きい場合は、集合の後半の中央の値を左半分または左半分まで比較し続けます。分割集合の右半分の値を比較する場合、現在の中間値の位置は、m に n を挿入した位置になります。
3. 1 と 2 の操作により、n を毎回挿入した後の m の集合がソートされたシーケンスであることが保証されます。
4. 1、2、3 の操作をループしてコレクション内のすべての値を 1 回挿入すると、並べ替えが完了します。

コード
private int[] array = {
    
    23, 11, 7, 29, 33, 59, 8, 20, 9, 3, 2, 6, 10, 44, 83, 28, 5, 1, 0, 36};

/**
 * 二分插入排序:从1开始遍历,已经遍历的数组中头是left,尾是right,遍历到的数字与中间的数字对比
 * 若小于中间的数字则right变更成中间数字前面的一个数字,反之则变更left
 * 直至最后left>right则插入
 */
private void binaryInsertSort() {
    
    
    for (int i = 1; i < array.length; i++) {
    
    
        int temp = array[i];
        int left = 0, right = i - 1;
        int mid;
        while (left <= right) {
    
    
            mid = (left + right) / 2;
            if (temp < array[mid]) {
    
    
                right = mid - 1;
            } else {
    
    
                left = mid + 1;
            }
        }
        // 将遍历到比他大的数字全部往后移一位
        for (int j = i - 1; j >= left; j--) {
    
    
            array[j + 1] = array[j];
        }
        array[left] = temp;
    }
}

2. ヒルソート

投稿への引用: https://www.jianshu.com/p/d730ae586cf3

3. 簡易選択ソート

アルゴリズム思考

小さいものから大きいものへの並べ替え:
1. すべての数値の最大の添え字を見つけます。
2. 毎回見つかった最大値が最後に固定されるように、最大​​値の添え字の位置を最後の位置の値と交換します。 3
.ループ 1、2 トラバースですべてが見つかるまで動作します。

コード
private int[] array = {
    
    23, 11, 7, 29, 33, 59, 8, 20, 9, 3, 2, 6, 10, 44, 83, 28, 5, 1, 0, 36};

/**
 * 选择排序:找到当前数中最大的数字,找到后与最后一个位置的数字交换位置,直至循环遍历完所有的数为止
 */
private void selectSort() {
    
    

    for (int i = 0; i < array.length; i++) {
    
    

        // 定义最大数字的下标,默认为0
        int max = 0;
        for (int j = 0; j < array.length - i; j++) {
    
    

            // 找到比自己大的数就更新下标
            if (array[max] < array[j]) {
    
    
                max = j;
            }
        }

        // 将找到最大的数与最后一个数字交换位置
        int temp = array[array.length - i - 1];
        array[array.length - i - 1] = array[max];
        array[max] = temp;
    }

}

kotlin言語の実装

class Solution {
    fun sortArray(nums: IntArray): IntArray {
        if (null == nums || nums.size == 0) {
            return nums
        }

        var length = nums.size

        while (length > 0) {
            var maxIndex: Int = 0
            for (i: Int in 0 until length) {
                //此处为升序排序
                    //若对数据进行降序排序,改为小于号即可,即 if (nums[i] < nums[maxIndex])
                if (nums[i] > nums[maxIndex]) {
                    maxIndex = i
                }
            }
            var temp = nums[length - 1]
            nums[length - 1] = nums[maxIndex]
            nums[maxIndex] = temp
            length--
        }

        return nums
    }
}

4. ヒープソート

投稿への引用: https://blog.csdn.net/l577217/article/details/80516654

5. バブルソート

アルゴリズム思考

1. 2 対 2 の比較。後者が前者より大きい場合、位置を交換します。
2. 円を横切るたびに最大の数が最後に来ます。その後、このラウンドの比較で最大値を決定し、
3. 1、2 をすべてループするまでループします。

コード
private int[] array = {
    
    23, 11, 7, 29, 33, 59, 8, 20, 9, 3, 2, 6, 10, 44, 83, 28, 5, 1, 0, 36};

/**
 * 冒泡排序:两两比较,大者交换位置,则每一圈比较最大的数就会冒到最后,循环直至遍历完所有
 */
private void bubbleSort() {
    
    

    for (int i = 0; i < array.length - 1; i++) {
    
    
        for (int j = 0; j < array.length - i - 1; j++) {
    
    
            if (array[j] > array[j + 1]) {
    
    
                int temp = array[j];
                array[j] = array[j + 1];
                array[j + 1] = temp;
            }
        }
    }
    
}

6. クイックソート

アルゴリズム思考

1. クイックソートの考え方は主に最初に基準点 m を設定することですが、ここでは毎回設定される基準点が各グループの最初の値であると仮定します。
2. セット内で比較する基準点 m を取得し、それを配置する位置を見つけます。
3. 比較方法は主に、コレクション内の左端の添字を左、右端の添字を右に定義します。m より小さい場合は左から比較を開始し、m より大きい場合は left++ を実行し、m より大きい場合は停止し、左の添字の値を右の添字の値として代入し、同様に右を比較し、mより大きければ右-、mより小さければ右-とします。左添え字の値が割り当てられます。left==right の場合、比較は完了します。
4. 手順 3 の比較後、m 点がソートされる位置がわかります。セットは 2 つの半分に分割され、それぞれ 1、2、3 に従ってソートされ、以下を再帰的に行ってソートが完了します。すべての分割と比較。

ステップ 3 の引用文は「ああ! 『アルゴリズム』という本からのイラスト。図では、最初の点 6 を基準点として、ソート後に 6 が配置されるべき位置が求められます。
ここに画像の説明を挿入
ここに画像の説明を挿入
ここに画像の説明を挿入
ここに画像の説明を挿入

コード
private int[] array = {
    
    23, 11, 7, 29, 33, 59, 8, 20, 9, 3, 2, 6, 10, 44, 83, 28, 5, 1, 0, 36};

/**
 * 快速排序:找到某个点排序之后它应该所在的位置
 */
private void quickSort() {
    
    
    quickSort(0, array.length - 1);
}

/**
 * 找到开始和结束位置之间以第一个数为基数,这个基数应该所在的位置
 * 找到之后以基数为中心点拆分成前后两段,依次递归进行本操作,直至最后遍历完所有基数为止
 *
 * @param low  开始的点下标
 * @param high 结束的点下标
 */
private void quickSort(int low, int high) {
    
    
    if (low >= high) {
    
    
        return;
    }
    int mid = getMiddle(low, high);
    quickSort(low, mid - 1);
    quickSort(mid + 1, high);
}

/**
 * 通过比较获取最开始基数最后所在的位置
 *
 * @param low  最开始的位置
 * @param high 结束的位置
 * @return 最后基数所在的位置
 */
private int getMiddle(int low, int high) {
    
    
    int temp = array[low];
    while (low < high) {
    
    
        while (low < high && array[high] >= temp) {
    
    
            high--;
        }
        array[low] = array[high];

        while (low < high && array[low] <= temp) {
    
    
            low++;
        }
        array[high] = array[low];
    }
    array[low] = temp;
    return low;
}

7. マージソート

アルゴリズム思考

1. データセットを 2 つの部分に分割します。
2. 各グループに 1 つだけが残るまでループを分割します。
3. 分割された配列を並べ替えて結合します。
4. 配列にマージされて並べ替えが完了するまで、ペアでマージします。
ここに画像の説明を挿入

コード
private int[] array = {
    
    23, 11, 7, 29, 33, 59, 8, 20, 9, 3, 2, 6, 10, 44, 83, 28, 5, 1, 0, 36};

/**
 * 归并排序:将数据集合两分拆开,直至最小之后两两排序合并
 */
private void mergeSort() {
    
    
    int[] temp = new int[array.length];
    mergeSort(temp, 0, array.length - 1);
}


/**
 * 查分数组,如果数组不能拆分了,则直接返回,拆分之后合并
 */
private void mergeSort(int[] temp, int start, int end) {
    
    

    if (start >= end) {
    
    
        return;
    }

    int mid = (start + end) / 2;
    mergeSort(temp, start, mid);
    mergeSort(temp, mid + 1, end);
    mergeArray(temp, start, mid + 1, end);
}


/**
 * 将数组array,以mid为中心,前后两个数组进行合并
 */
private void mergeArray(int[] temp, int start, int mid, int end) {
    
    

    // 定义指针下标,记录前后段是够可以继续移动
    int minA = start, minB = mid;
    for (int i = start; i <= end; i++) {
    
    
        if (minA >= mid || minB > end) {
    
    
            // 如果a或者b用完了,则直接用对方的
            if (minA >= mid) {
    
    
                temp[i] = array[minB];
                minB++;
            } else {
    
    
                temp[i] = array[minA];
                minA++;
            }
        } else {
    
    
            // 都没用完则比较大小
            if (array[minA] < array[minB]) {
    
    
                temp[i] = array[minA];
                minA++;
            } else {
    
    
                temp[i] = array[minB];
                minB++;
            }
        }
    }

    System.arraycopy(temp, start, array, start, end - start + 1);
}

8. 基数ソート

投稿への引用: https://blog.csdn.net/lrxb_123/article/details/115013190

おすすめ

転載: blog.csdn.net/lrxb_123/article/details/114980572