グッドタイムズ[]データ構造の挿入ソート、バイナリ検索の最適化

テン古典的なソートアルゴリズム!
ここに画像を挿入説明

序文

してください必ずこれを見て:準備のアルゴリズム事前知識+コード環境をソートします

上記の内容は準備ができたら、それは一種の挿入を開始します!

挿入ソート

トランプを挿入ソートに非常に似てソート、カードの裏面には絵の前に挿入され、そのフロントカード秩序あることが徐々に増加し、完全に注文したまで。
ここに画像を挿入説明

ここに画像を挿入説明
実装プロセス

  • ①実行時には、二つの部分に挿入されたシーケンスをソートします
    ヘッドの既にされているソート尾があるソートするには
  • ②各走査素子を傷つける
    ヘッドデータが整然と残るようにその都度走査要素、それはヘッドの適切な位置に挿入されます

挿入ソート達成します

/**
 * 插入排序
 */
public class InsertionSort1 <T extends Comparable<T>> extends Sort<T>{

	@Override
	protected void sort() {
		for(int begin = 1; begin < array.length; begin++){
			int cur = begin;
			while(cur > 0 && cmp(cur, cur-1) < 0){
				swap(cur, cur - 1);
				cur--;
			}
		}
	}

}

20000の値は[1、10000]乱数でソートされ生成されます。
ここに画像を挿入説明

挿入ソート - 逆にします

逆の順番とは何ですか?

  • アレイ<2、3、8、6、1>は逆の順序である
    <2,1> <3,1> <8,1> <8,6> <6,1>、5つの逆順の合計

の時間複雑さの逆の挿入ソートの数に比例

  • 逆より多くの、挿入ソートの高い時間複雑

明らかに、図中上から下へは、挿入ソート、徐々に効率を高めます
ここに画像を挿入説明

挿入ソート - 最適化

アイデアは、[為替] [へ]移動することです

実装プロセス:

  • 挿入される最初のバックアップ要素①
  • ②順序付けられたデータ要素よりも大きな頭部が挿入さ、方向後方位置に向かって移動しています
  • ③要素は、最終的な場所に挿入されます

ここに画像を挿入説明

/**
 * 插入排序-优化
 * 交换  -> 挪动
 */
public class InsertionSort2 <T extends Comparable<T>> extends Sort<T>{

	@Override
	protected void sort() {
		for(int begin = 1; begin < array.length; begin++){
			int cur = begin; 
			T v = array[begin]; // 将待插入元素备份
			while(cur > 0 && cmp(v, array[cur-1]) < 0){
				// 头部有序数据中比待插入元素大的,都朝尾部方向挪动1个位置
				array[cur] = array[cur - 1]; 
				cur--;
			}
			array[cur] = v; // 将待插入元素放到最终的合适位置
		}
	}

}	

見つけることができる:20000の値は[1、10000]ランダムな番号でソートされた生成交換の数が0になります
ここに画像を挿入説明

複雑性と安定性

  • 最悪、平均時間計算:O(N- 2
  • 最高の時間の複雑さ:O(n)は、
  • 宇宙複雑:O(1)
  • 属する安定したソート
  • ときに非常に少ない、効率の挿入ソートが特に高いの逆
    であっても速度O(nlog比N速いクイックソート)レベル

データ量が特に大きくはない、効率の挿入ソートも非常に良いです。

バイナリ検索

配列内の要素の位置を確認する方法?(アレイ内のすべての仮定は整数です)

  • O(N):アレイは0トラバーサル検索開始位置、平均時間の複雑さから、乱れている場合
    ここに画像を挿入説明
  • (ログインO:配列を注文した場合、バイナリ検索は、最悪時間計算量を使用することができますN-
    ここに画像を挿入説明

バイナリ検索 - アイデア

  • Vは、検索の要素が[END)レンジ、中間==(+端を開始)/ 2、始めることが想定されます
  • V <mは、[バイナリ探索の範囲で、中間)を開始する場合
  • V> mの場合に、[中間+ 1、端部)に二分探索の範囲内
  • V ==メートルの場合、直接のリターン中旬
    ここに画像を挿入説明
    ここに画像を挿入説明

バイナリ検索 - 達成

/**
 * 二分搜索
 */
public static int search(int[] array, int v){
	if(array == null || array.length < 1) return -1;
	int begin = 0;
	int end = array.length;
	while(begin < end){
		int mid = (begin + end) >> 1;
		if(v < array[mid]){
			end = mid;
		}else if(v > array[mid]){
			begin = mid + 1;
		}else{
			return mid;
		}
	}
	return -1;
}

複数の重複する値が存在する場合、リターンはありますか?

  • 不確実

挿入ソート - バイナリサーチの最適化

挿入要素中Vは、することが可能であるバイナリ適切な挿入位置を検索しそしてその要素vを挿入します

:以下の配列と仮定
ここに画像を挿入説明
項バイナリ検索返さ挿入位置:Vよりポジション以上の最初の要素を

  • vが5、返品の場合は2
  • vが1である場合は、0が返されます
  • vが15、7リターンである場合
  • vが8であれば、返す5

挿入ソート - バイナリ検索の最適化 - アイデア

  • Vは、検索の要素が[END)レンジ、中間==(+端を開始)/ 2、始めることが想定されます
  • V <mは、[バイナリ探索の範囲で、中間)を開始する場合
  • V≥Mの場合、バイナリサーチの範囲の[中間+ 1、端部)まで

ここに画像を挿入説明

挿入ソート - セカンド検索の最適化 - 例

ここに画像を挿入説明
ここに画像を挿入説明
ここに画像を挿入説明

挿入ソート - バイナリ検索の最適化 - 実現

/**
 * 插入排序-优化2
 * 二分搜索进行优化
 */
public class InsertionSort3 <T extends Comparable<T>> extends Sort<T>{

	@Override
	protected void sort() {
		for(int begin = 1; begin < array.length; begin++){
			// 将遍历到的元素插入到前面已经排好序的序列中
			insert(begin, search(begin)); //search() 查找到要插入的位置
		}
	}
	
	/**
	 * 将source位置的元素插入到dest位置
	 */
	private void insert(int source, int dest){
		T v = array[source]; // 备份要插入的元素
		// 将 [insertIndex, begin)范围内的元素往右边挪动一个单位
		for(int i = source; i > dest; i--){
			array[i] = array[i - 1];
		}
		array[dest] = v;
	}
	
	/**
	 * 利用二分搜索找到index位置元素的待插入位置
	 * 已经排好序数组的区间范围是[0,index)
	 */
	private int search(int index){
		int begin = 0;
		int end = index;
		while(begin < end){
			int mid = (begin + end) >> 1;
			if(cmp(array[index], array[mid]) < 0){
				end = mid;
			}else{
				begin = mid + 1;
			}
		}
		return begin;
	}
	
}

20000の値は[1、10000]乱数でソートされ生成されます。
ここに画像を挿入説明

複雑性と安定性

唯一比較の数を減少させる、二分探索を使用して、しかし後の挿入ソート平均時間計算量は依然としてO(N 2

  • 最悪、平均時間計算:O(N- 2
  • 最高の時間の複雑さ:O(n)は、
  • 宇宙複雑:O(1)
  • 属する安定したソート
公開された170元の記事 ウォン称賛47 ビュー20000 +

おすすめ

転載: blog.csdn.net/weixin_43734095/article/details/105123621