光Javaのソートアルゴリズムへの光

JavaのStringソートアルゴリズムのソースコード

I.はじめに

Q:選択肢は何ですか?
選択は、設定数Nが、Kの目によって最大値を決定することが想定されます。例えば、Aと大きいBのオブジェクトが必要ですか?別の例:配列から項目の最大数を見つけることを検討するには?

問題を解決する選択し、あなたが目標容量を持っている必要があり、それは、任意の2つのオブジェクトを比較し、小さいか等しいである大規模などの、決定することです。比較的長いオブジェクト(同等)容量、回覧オブジェクトリストに続いてアイテムの最大の問題は、解決策を見つけ、一つは解決することができます。

だから、JDKのソースコードは、それより多くの(同等の)能力を達成するためにどのように?

二、java.lang.Comparableとインタフェース

ファイル

匹敵します インタフェースは、JDK 1.2のバージョンがあり、長い歴史を検討しました。比較できます インタフェースは、オブジェクトの実装クラスのソートされたリストを余儀なくされました。どちらが自然順ソートと呼ばれる compareTo 自然の比較として知られている方法、。

インタフェースは唯一の方法であるpublic int compareTo(T o);、それは見ることができます

  • 基準T 0へ:比較する着信オブジェクトに対応するインタフェースクラスを実装
  • 戻り値INT:未満と等しい、より大きいを表す、正、負、および0

セットリスト(コレクションリスト)またはオブジェクトの配列(配列)、だけでなく、簡単に使用することができ、対応するツール:

  • java.util.Collections#ソート(リスト)リストの並べ替え
  • java.util.Arrays#ソート(オブジェクト[])ソートされた配列

そのStringオブジェクトはどのように比較しますか?

三、文字列のアルゴリズムのソースコード

文字列のソース列JDK 1.0を見ることができます。1.2 JDKなければならないときに、StringクラスはComparableインタフェースを実装し、比較されているオブジェクトを渡す必要はStringです。図は、オブジェクト:

ファイル

文字列は、最終的なクラスは、文字列から新しいクラスを拡張することはできませんです。ライン114から、ストレージ構造は、文字列(CHAR)アレイであることがわかります。まず、あなたは文字列の比較のケースを見ることができ、以下のように、コードは次のとおりです。


/**
 * 字符串比较案例
 *
 * Created by bysocket on 19/5/10.
 */
public class StringComparisonDemo {
    
    public static void main(String[] args) {
        String foo = "ABC";
        
        // 前面和后面每个字符完全一样,返回 0
        String bar01 = "ABC";
        System.out.println(foo.compareTo(bar01));
        
        // 前面每个字符完全一样,返回:后面就是字符串长度差
        String bar02 = "ABCD";
        String bar03 = "ABCDE";
        System.out.println(foo.compareTo(bar02)); // -1 (前面相等,foo 长度小 1)
        System.out.println(foo.compareTo(bar03)); // -2 (前面相等,foo 长度小 2)
        
        // 前面每个字符不完全一样,返回:出现不一样的字符 ASCII 差
        String bar04 = "ABD";
        String bar05 = "aABCD";
        System.out.println(foo.compareTo(bar04)); // -1  (foo 的 'C' 字符 ASCII 码值为 67,bar04 的 'D' 字符 ASCII 码值为 68。返回 67 - 68 = -1)
        System.out.println(foo.compareTo(bar05)); // -32 (foo 的 'A' 字符 ASCII 码值为 65,bar04 的 'a' 字符 ASCII 码值为 97。返回 65 - 97 = -32)
        
        String bysocket01 = "泥瓦匠";
        String bysocket02 = "瓦匠";
        System.out.println(bysocket01.compareTo(bysocket02));// -2049 (泥 和 瓦的 Unicode 差值)
    }
}

結果は以下の通りであります:

0
-1
-2
-1
-32
-2049

図から分かるように、compareToそれは2つの文字列を辞書と比較することです。特定のルールの比較は、コードのコメントを見ることができます。次のルールを比較します。

  • 各文字列は、0を返し、まったく同じです
  • 文字列の各文字は、前のセクション、リターンとまったく同じである:長さの差は、二つの文字列の後ろにあります
  • 各文字列は、フロント部分に存在する同じではありません、返す:ASCII文字が表示されるとの違いは、同じではありません
    • リターンに対応する比較中国語Unicodeコード値(UnicodeはASCIIが含ま)
    • 文字のASCIIコードでfoo「でC」は67です
    • 文字のASCIIコードでbar04「D」は68です。
    • foo.compareTo(bar04)は、67--68 = -1を返し
    • 図に示すように、共通のASCII文字コード、

ファイル

文字列を見てcompareTo辞書順を達成するためにどのような方法。ソース・図:

ファイル

次のようにソースに解釈しました:

  • 行1156:現在の文字列と別の文字列、小さい方の長さの値LIMを取得
  • 行1161:LIMは0(小さな非空の文字列)よりも大きければ、比較が開始されます
  • 1164ライン:現在の文字列と文字とを比較することによって、その後別の文字列、。差が等しくない場合は、Unicodeエンコーディング値の2つの文字を返し
  • 1169ライン:現在の文字列と文字とを比較することによって、その後別の文字列、。両者が等しい場合、二つの文字列の長さの差が返されます

だから、ソートするために、Comparableインタフェースを実装するより多くの機能を持っているようにしてください。このオブジェクトのリストを得る(及びアレイ)インターフェイスCollections.sort(とは、Arrays.sort)を介して注文することができます。

そこTreeSetのツリー構造(赤黒木)を使用して実装、コレクションの要素を並べ替えます。匹敵するこのインタフェースを実現するためにはどのようなものです

並べ替えを使用して、Comparableインタフェースを実装していない場合はまた、java.lang.ClassCastExceptionが、例外がスローされます。詳細はを見て、「Javaコレクション:三、HashSetの、TreeSetのと比較LinkedHashSetの」https://www.bysocket.com/archives/195

IVの概要

上記でも述べた、実際には、この比較は、いくつかの欠点があります:

  • デフォルトの文字ケースを無視しないのcompareTo。あなたが無視したい場合は、compareToメソッドを再カスタマイズ
  • 決定は二次元で比較することはできません。例えば、大きい2 * 3 * 3 1矩形と矩形を決定するために?
  • 例えば、いくつかのクラスは、インターフェイスを実装することはできません。finalクラスは、新しいクラスを拡張することはできません。また、解決策があります:関数オブジェクト(関数オブジェクトを)

方法パラメータ:だけでなく、データを処理するクラスを定義し、クラスのインスタンスを渡します。転送するターゲットの内側にそれを置くことによって機能。多くの場合、関数オブジェクトと呼ばれるこのようなオブジェクト(目的球オブジェクト)

インターフェイスメソッドの設計では、 T(コールバックを実行します コールバック)コールバックは、同様のパラメータが使用されます。重合優先継承または実装:ばねの例は、ソースコードに、多くの設計はそれを見ることができます。これは、継承されたか、達成の多くを減らすことができます。同様のSpringJdbcTemplateシーンの設計は、そのようなコールバックの設計と実装を検討してください。

その挿入は、それを並べ替えますか?

記事のプロジェクト:

  • JDK 1.8
  • プロジェクト名:アルゴリズムコア学習
  • プロジェクトアドレスします。https://github.com/JeffLi1993/algorithm-core-learning

I.はじめに

上記のソートアルゴリズムJavaのString源は、選択肢が何であるかに言えば、より多くの容量ものです。

選択は、設定数Nが、Kの目によって最大値を決定することが想定されます。この問題を解決するためのアルゴリズム。

アルゴリズムとは何ですか?
これは、いくつかのアルゴリズムのコレクション、命令の簡単なセット、指定された命令の簡単なセットです。重要な指標を決定するためのアルゴリズム:

  • これで問題が解決するかどうか最初に。
  • 結果が必要などのくらいの時間の問題を解決するために、つまり、時間を実行している第2のアルゴリズム。
  • メモリなどがあり必要なスペース資源、。

作業プログラムを書くことは多くの場合、十分ではありません。大規模なデータが発生したので、実行時間が重要な課題です。

アルゴリズムの性能は、大きいO表記で表されます。Oマーク表記は精度が粗い、大きな相対成長率です。例えば2N及び3N + 2のために、O(N)です。それは、多くの場合、直線的な成長を言われて、指数関数的な成長、などということが多いが言われています

典型的な成長率

ファイル

典型的なアプローチは、分割統治の性能を提供するために分割統治戦略の分岐です。

  1. 問題は、サブ部分である、再帰的にそれらを解決する2つのほぼ等しいサブ問題に分割されます。
  2. 治療一緒にパッチ適用の問題を解決し、再度実行する追加作業の少量の二つのサブステージは、最終的には全体の問題の解決策を得ました。

ファイル

第二に、ソート

ファイル

スケジューリング問題は、古いですが、人気のある質問となっています。暴露からACMは、今や各関わるアルゴリズム、いくつかのアルゴリズムまたはJDKのソースコードの読み物を動作させるには、多くの場合、ソートアルゴリズムが表示されています。

アレイ(または配列)のセットにアルゴリズムをソート降順(或いは昇順)順序に沿ってデータ配置を並び替えます。オーダーへの障害からこのようなデータを、どのようなメリット?

  • アプリケーションレベル:問題を解決します。
    • 最も簡単には最大または最小を見つけることです
    • 一緒に「一緒に」問題の解決、すなわち、同じマーク要素
    • プロジェクト内の2つの以上のファイルを一致させます
    • キーコードによって情報を見つけます
  • システムレベル:システムの昇順、システムのエントロピーを減らすために
    (ドナルド・クヌースの古典的な「コンピュータプログラミングのアート」コンピュータプログラミングの(アート)ボリュームIII)

ウィキペディアで得られた情報へのアクセス:
メインメモリに完成し、配列決定、内部順序と呼ばれています。これは、ディスクや外部の仕分け外部ソートと呼ばれる他のストレージ並べ替えを完了する必要があります。プロフィール住所ます。https://en.wikipedia.org/wiki/External_sorting

前の「JavaのStringソートアルゴリズムのソースコードは」、java.lang.Comparableとインタフェースについて話しました。そうインターフェースは抽象型である、抽象メソッド(のcompareTo)の集合であり、インターフェイスで宣言。従ってタイプに属する同等のソートオブジェクトは、すなわち、同等のインタフェースを実現し、その後のcompareToソート比較達成オブジェクトのメソッドを呼び出します。

これらの条件下で呼ばれるソートは、比較(比較ベースのソート)に基づいてソート

第三に、挿入ソート

方言:ビッグベアーは、(a)は、ローからハイキュー(ソート)までの高さに合わせて2、3 ...クマを負担します。クマNはチームに参加し、この時間は、それが尾からチームを比較し始めました。それはフロントクマの高さ、交換位置との比較よりも低い場合、順次尾部から頭部に比べ&交換位置。Nが負担すべき場所への最終的な変更。これは、挿入ソートの原理です。

挿入ソート(挿入ソート)

  • 最も簡単な種類の一つ。PS:バブルソートのように見えるが、学習のために推奨されていません
  • N - 成る1回ソーティングプロセス。
    • そのような要素がソートされている場合は、ソートは必要ありません。すなわち、N = 1(1 - 1 = 0)
    • 現在の位置状態要素への最初の位置から各ソート保証は、ソートされます。
  • 図:フォワード各要素を比較し、それらの位置で終端

ファイル

/**
 * 插入排序案例
 * <p>
 * Created by 泥瓦匠@bysocket.com on 19/5/15.
 */
public class InsertionSortingDemo {
    
    /**
     * 插入排序
     *
     * @param arr 能比较的对象数组
     * @param <T> 已排序的对象数组
     */
    public static <T extends Comparable> void insertionSort(T[] arr) {
        int j;
        
        // 从数组第二个元素开始,向前比较
        for (int p = 1; p < arr.length; p++) {
            T tmp = arr[p];
            // 循环,向前依次比较
            // 如果比前面元素小,交换位置
            for (j = p; (j > 0) && (tmp.compareTo(arr[j - 1]) < 0); j--) {
                arr[j] = arr[j - 1];
            }
            // 如果比前面元素大或者相等,那么这就是元素的位置,交换
            arr[j] = tmp;
        }
    }
    
    public static void main(String[] args) {
        Integer[] intArr = new Integer[] {2, 3, 1, 4, 3};
        
        System.out.println(Arrays.toString(intArr));
        insertionSort(intArr);
        System.out.println(Arrays.toString(intArr));
    }
}

コード解析、次のように:

  • 配列の2番目の要素からは、前方の比較を開始します。最初の要素よりも小さい、次にスイッチ位置
  • 次いで、第三、第四など、比較の2番目の要素であれば...
  • シーケンシングを完了するために、最後の要素を比較した場合

時間計算量は、最良のシナリオは、ソートが正しく配置されたことがO(N ^ 2)であることが条件決意サイクルを満たすことができないので、それは、O(N)であり、逆の順序で最も極端なアレイ、すなわち(OでありますN ^ 2)。したがって、アルゴリズムの時間複雑度は、O(N ^ 2)であります

、次のような結果をmainメソッドの実行:

[2, 3, 1, 4, 3]
[1, 2, 3, 3, 4]

そして、最適化について考え、それを最適化する方法でしょうか?
挿入ソートより前方より最適化バージョン。前半の比較、良くなる可能性が高い二点。特定のコード、自身が試すことができます

四の挿入ソート、ののArray.sortソース

達成するために自分自身をソートするために使用上の挿入アルゴリズムは、実際にはJDKのArray.sortは簡単にソートするための方法を提供します。次のようにケースのコードは次のとおりです。

/**
 * Arrays.sort 排序案例
 * <p>
 * Created by 泥瓦匠@bysocket.com on 19/5/28.
 */
public class ArraysSortDemo {
    
    public static void main(String[] args) {
    
        Integer[] intArr = new Integer[] {2, 3, 1, 4, 3};
    
        System.out.println(Arrays.toString(intArr));
        Arrays.sort(intArr);
        System.out.println(Arrays.toString(intArr));
    }
}

、次のような結果をmainメソッドの実行:

[2, 3, 1, 4, 3]
[1, 2, 3, 3, 4]

それは、Arrays.sortは、それを達成する方法ですか?JDK 1.2ではアレイ、JDK 1.8バージョンソートアルゴリズムを最適化する際とき。次のように:

  • 要素の数は、挿入ソートを使用して、47未満である場合
  • 要素の数は、高速なソートを使用して、286未満の場合
  • Timsort積分アルゴリズムのマージソートや挿入ソート

ファイル

上記と同じ目的を達成するために挿入ソートアルゴリズムを統合し、我々はマージソートを参照してくださいソースコード。ここでは、ラインの説明で並ぶありません。

V.の概要

この問題を解決するためのアルゴリズム。必ずしも複数の問題を解決することがあり、問題を解決するためのアルゴリズムではありません。最適なソリューションを実現しています。挿入ソートは、それは簡単なことです

サンプルコード

読者は、以下の倉庫で、この記事の例を見ることができます:StringComparisonDemo文字列の比較ケースケース:

参考資料

  • 「データ構造とアルゴリズム解析:(オリジナルブック第3版)を記述するためのJava言語」
  • https://en.wikipedia.org/wiki/Unicode
  • https://www.cnblogs.com/vamei/tag/%E7%AE%97%E6%B3%95/
  • https://www.bysocket.com/archives/2314/algorithm

おすすめ

転載: www.cnblogs.com/Alandre/p/11524985.html