第四に、並べ替え(ソートアルゴリズム)
記事のディレクトリ
1、の概念
ソートの概念:ソート処理が指定された順序で配置されたデータの集合です。
ソートはソートされ、ソート処理内のすべてのデータが内部メモリにロードされ、ソート外部および内部ソートに分けることができます。
データはすべてメモリにロードするには大きすぎる場合は、必要性は、外部記憶装置を用いてソートします。
1.1、内部ソート
- 挿入ソート
直接挿入ソート、シェルソート
- 選択ソート
単純な選択ソート、ヒープソート
- ソート交換
バブルソート、クイックソート
- マージソート
- 基数ソート
1.2外部ソート
2、ソートのアルゴリズム
2.1バブルソート
コンセプト:バブルソート為替の一種で、その基本的な考え方です:いくつかの順序規則に従って、隣接する2つの重要な要素、交換は、逆の順序である場合には逆の順序でレコードが存在しなくなるまで。
-
通常のバブルアルゴリズム
for (int i = 0; i < arr.length - 1; i++) { for (int j = 0; j < arr.length - 1 - i; j++) { if (arr[j] > arr[j + 1]) { swap(arr, j, j + 1); } } System.out.println(Arrays.toString(arr)); }
-
アルゴリズムの最適化をソート
何のデータ交換がない場合、このシーケンスの、すなわち記述が注文された場合は、データバックを決定する必要がすなわち、ありませんが、我々はコードを最適化する必要がある、すなわち、シーケンスが注文された際に、データがの裏にはもはやありません判決。
boolean flag = true; for (int i = 0; i < arr.length - 1&&flag; i++) { flag=false; for (int j = 0; j < arr.length - 1 - i; j++) { if (arr[j] > arr[j + 1]) { swap(arr, j, j + 1); flag = true; } } System.out.println(Arrays.toString(arr)); }
2.2簡単な選択ソート
:コンセプト(それ自身を含む)1 + NI最小キー選択された記録の記録からNIキーワードとの比較を通じて、であり、i番目の記録と交換。
for (int i = 0; i < arr.length - 1; i++) {
int minSize = i;
int min = arr[minSize];
for (int j = i + 1; j <= arr.length - 1; j++) {
if(min>arr[j]){
minSize=j;
min=arr[j];
}
}
if(i!=minSize){
arr[minSize]=arr[i];
arr[i]=min;
}
}
直接挿入ソート2.3
概念:n番目の要素であることを命じ参照順不同および順序リストテーブルとしては、注文テーブルは順序付けられていないリストの先頭に1つのだけの要素が含まれているが乱れ各ソート処理からn-1の要素が含まれテーブル内の最初の要素を削除し、それを順次ソートコードがソートキーの要素の順序付きリストと比較され、それが新たなテーブルになるために、順序付けされたリスト内の適切な位置に挿入されます。
int insertScrpt=0;//要插入的位置
int insertValue=0;//插入的值
for(int i=1;i<=arr.length-1;i++){
insertScrpt=i-1;
insertValue=arr[i];
while (insertScrpt>=0&&insertValue<arr[insertScrpt]){
arr[insertScrpt+1]=arr[insertScrpt];//向后移
insertScrpt--;
}
if(insertScrpt+1!=i){
arr[insertScrpt+1]=insertValue;
}
}
2.4シェルソート
概念:シェルソート単位で記録パケット、直接挿入ソート各ソートアルゴリズムの使用を押すの主題である。減少刻みで、各キーワードが増分が低減され、より多く含まれている場合1は、ファイル全体がピンチアルゴリズム終了のセットに分割されています。
-
取引所(複雑さが17Sについてです時間)
int temp = 0; for (int increment = arr.length / 2; increment > 0; increment = increment / 2) { for (int i = increment; i < arr.length; i++) { for (int j = i - increment; j >= 0; j -= increment) { if (arr[j] > arr[j + increment]) { temp = arr[j]; arr[j] = arr[j + increment]; arr[j + increment] = temp; } } } System.out.println(Arrays.toString(arr)); }
-
シフト方式(時間の複雑さは、約1sです)
for (int increment = arr.length / 2; increment > 0; increment = increment / 2) { for (int i = increment; i < arr.length; i++) { int j = i; int temp = arr[j]; if (arr[j] < arr[j - increment]) { while (j - increment >= 0 && temp < arr[j - increment]) { arr[j] = arr[j - increment]; j -= increment; } arr[j] = temp; } } System.out.println(Arrays.toString(arr)); }
2.5クイックソート
思想は:クイックソートは、2つの別個の部分にソートするソート、ソートのデータによってトリップする泡の向上、データの他の部分よりも小さいすべてのデータのこの方法の特徴部分でありますデータの2つの部分は、全体のソート処理が全体のデータが、順序付けられたシーケンスとなり達成するために再帰的にすることができ、クイックソートでした。
public static void quickSort(int[] arr,int left,int right){
int l=left;
int r=right;
int temp=0;
int privot=arr[(right+left)/2];
while (l<r){
while (arr[l]<privot){
l++;
}
while (arr[r]>privot){
r--;
}
if(l>=r){
break;
}
temp=arr[l];
arr[l]=arr[r];
arr[r]=temp;
if(arr[l]==privot){
r--;
}
if(arr[r]==privot){
l++;
}
}
if(l==r){
l+=1;
r-=1;
}
//左递归
if (left<r){
quickSort(arr,left,r);
}
//向右递归
if(right>l){
quickSort(arr,l,right);
}
}
2.6マージソート(マージ)
マージソートのアイデアは、古典的な使用して、マージソート方法を使用することで分割統治戦略を(分割統治が小さい問題、その後、再帰的なソリューションに問題を破るためにある、それは一緒にパッチ適用のすべての段階にお答えします)
オンライングラフィック検索
の完全なバイナリツリーをしたいと思い、このようなAの構造を、我々が達成するために、再帰的なメソッドを使用し、あなたはまた、再帰分割シーケンスとして理解することができる段階的なプロセスを実現するために、反復的なアプローチを取ることができます。
-
スプリットシーケンス
public static void mergeSort(int[] arr, int left, int right, int[] temp) { if (left < right) { int mid = (left + right) / 2; //向左递归分解 mergeSort(arr, left, mid, temp); //向右递归分解 mergeSort(arr, mid + 1, right, temp); //合并 merge(arr, left, mid, right, temp); } }
-
組み合わせシーケンス
/** * 合并 * * @param arr 原始数组,待排序的数组 * @param left 数组的左边坐标 * @param mid 数组的中间坐标 * @param right 数组的右边坐标 * @param temp 临时数组 */ public static void merge(int[] arr, int left, int mid, int right, int temp[]) { int i = left;//初始化i,左边序列的初始索引 int j = mid + 1;//初始化j,右边序列的初始索引 int t = 0; //临时变量的索引 //1、将拆开的左右数组中的元素分别比较大小,并放入临时数组,直至某一数组被放完 while (i <= mid && j <= right) { if (arr[i] < arr[j]) { temp[t] = arr[i]; i++; t++; } else { temp[t] = arr[j]; j++; t++; } } //2、将剩下数组的元素全部移动到临时数组中 while (i <= mid) { temp[t] = arr[i]; i++; t++; } while (j <= right) { temp[t] = arr[j]; j++; t++; } //3 将临时数组的元素合更新到原数组 t = 0; int tempLeft = left; while (tempLeft <= right) { arr[tempLeft] = temp[t]; t++; tempLeft++; } }
2.7基数ソート(延長のバケットソート)
アルゴリズムの説明:デジタル基数ソートバケットに指定されたサイズのそれぞれに応じて、それぞれのために分離され、バケットは、配列によって表される番号0-9タブに分割されています。そのような249のように、分離・ビットは、単離された10は、タブ4、千の単離された位置、0の数にバケット249に246番のタブ9に249番号。シーケンス現在、負の基数ソートを使用することはできません。
基本的な考え方:すべて同じ桁長の数値団結、ゼロビットの数短いフロント補完し、その後、最低のスタートから、一度そう最低のソートからの最高の並べ替え後まで、ソートを比較するために完了すると、列の数それは、順序付けられたシーケンスになります。
public static void radisSort(int[] arr){
//找出最大数并确定位数
int max=arr[0];
for(int i=1;i<arr.length;i++){
if(max<arr[i]){
max=arr[i];
}
}
int maxLength=(max+"").length();
//定义桶,为了防止元素溢出,需要将每个桶的容量都定义为:arr.length
int[][] bucket=new int[10][arr.length];
//定义一个数组bucketElementCount[],用来记录每个桶中放入的元素的数量
int[] bucketElementCount=new int[10];
/**
* 将数据元素放入桶中
*/
for(int l=0,n=1;l<maxLength;n=n*10,l++){
for(int i=0;i<arr.length;i++){
int endDigital=arr[i]/n%10;
bucket[endDigital][bucketElementCount[endDigital]]=arr[i];
bucketElementCount[endDigital]++;
}
/**
* 取出元素
*/
int index=0;
for(int i=0;i<bucket.length;i++){
if(bucketElementCount[i]!=0){
for(int j=0;j<bucketElementCount[i];j++){
arr[index]=bucket[i][j];
index++;
}
}
//将bucketElemnetCount清零
bucketElementCount[i]=0;
}
System.out.println(Arrays.toString(arr));
}
}