ソートアルゴリズムの並べ替えをマージ
マージソートは、分割と征服戦略、分割と征服のアプリケーションの1つです。
時間の複雑さはO(n log n)
です。マージソートの考え方は、キューを分割できないまでサブキューに分割し、サブシーケンスをマージして完全に順序付けられたシーケンスを取得することです。つまり、最初に各サブシーケンスに順序付けしてから、サブシーケンスセグメントを順番に作成します。
芯
マージソートのコアがある
分治思想
と递归实现
- 戦略を分割して征服する:元の問題をいくつかの小さいが類似したサブ問題に分解し、これらのサブ問題を再帰的に解決してから、サブ問題の解決策をマージして元の問題の解決策を確立します。
写真も真実もありません、ソートフローチャートをマージします(海賊Baidu Baike?)
アルゴリズムの分析
- 最初に、キュー内の要素の数が1になるまで、キューを再帰的に分解します(中間点分解を使用)。
- 分解キューは、キューの中点を計算することにより、左キュー(低、中)と右キュー(中+ 1、高)に分割されます。
- 元のキューが最小のキューに分割されると(キューには要素が1つしかない)、サブキューが順序付けられます
- 2つの順序付けされたキューを1つの順序付けられたキューに結合します。コードの
mergeArray
メソッド
コード
コメントはより詳細なので、詳細には触れません
/**
*
* @param array 排序数组
* @param start 开始位置
* @param end 结束位置
*/
private void mergeSort(int[] array, int start, int end) {
if (start < end) {
//当数组中的元素不可分时,停止分解
int mid = (start + end) / 2;//计算中间坐标
mergeSort(array, start, mid);//递归分解数组
mergeSort(array, mid + 1, end);//递归分解数组
//合并数组,合并后为有序数组
//因为前面为递归调用,所以可以保证第一次调用此方法时,子数组长度为1
mergeArray(array, start, mid, end);
}
}
private void mergeArray(int[] array, int start, int mid, int end) {
int[] left = new int[mid - start + 1 //存放数据长度
+ 1];//预留安全守卫
int[] right = new int[end - mid//存放数据长度
+ 1];//预留安全守卫
System.arraycopy(array, start, left, 0, left.length - 1);
System.arraycopy(array, mid + 1, right, 0, right.length - 1);
left[left.length - 1] = SAFE_GUARD;
right[right.length - 1] = SAFE_GUARD;
int l = 0, r = 0;
for (int i = start; i <= end; i++) {
if (right[r] == SAFE_GUARD) {
array[i] = left[l];
}
if (left[l] == SAFE_GUARD) {
array[i] = right[r];
}
if (left[l] <= right[r]) {
array[i] = left[l];
l++;
} else {
array[i] = right[r];
r++;
}
}
}
結論
私は個人的に、マージとソートについて重要なことは、分割して征服するという考えだと思います。戦略を分割して征服する
JDK7
アプリケーションForkJoinPool
も導入されました。その場合、あなたは分裂と征服の戦略を理解する必要があります!
「アルゴリズム入門」2日目、さあ!次分治策略