序文
この時間は自宅で仕事をするので、すべての私たちは、自分の考えを整理するために多くの時間を持っています。今日は主にアルゴリズムが並べ替えいくつかの簡単な説明を
、この時間は、我々は適切に次の手がかりを整理し、良いプランを取得するために努力を願って、いわゆる「金と銀3 4」に行ってきました、ちょうど仕事への復帰であります
GitHubのフォローアップ関連コンテンツの更新が、私はスターを歓迎し、見て、見ることができるインパクト金と銀3人の4人の小さなパートナーにしたい
(引か左GitHubのリンク、あなたは自分自身を見つけることができる、そのようなインタビューなどの関連コンテンツへのアクセスを必要とします)
https://github.com/xiangjiana/Android-MS
(VX:mm14525201314)
バブルソートディアン
基本的な考え方:
隣接する要素の比較。最初は、二以上である場合には、それらの2を交換しました。最初から最後のペアの最初の終わりには、隣接する要素のペアごとに同じ作業を行います。この時点で、それは最後の要素は、最大数であるべきです。最後の1を除いて、すべての要素について、これらの手順を繰り返します。比較する必要がなくなるまで、各時間より少ないと少ない要素、数字のペアのための上記の手順を繰り返し続けました。
Java実装は、
泡の状態フラグは、実行しているときに低下は停止することができない交換がなければタグを追加します
public static void bubbleSort(int[] numbers) {
int temp = 0;
int size = numbers.length;
boolean flag = true;
for (int i = 0; i < size - 1&&flag; i++) {
flag = false;
for (int j = 0; j < size - 1 - i; j++) {
if (numbers[j] > numbers[j + 1]) // 交换两数位置
{
temp = numbers[j];
numbers[j] = numbers[j + 1];
numbers[j + 1] = temp;
flag = true;
}
}
}
}
二ディアン選択ソートアルゴリズム
基本的な考え方:
グループの数は、ソート、第1のスイッチング位置の数の最小数を選択すると、次にその中の残りの数、および最後から二番目の上に第2のスイッチング位置の最小数を見つけます。数とこれまでの最後の番号の比較。
Java実装
public static void selectSort(int[] numbers) {
int size = numbers.length; // 数组长度
int temp = 0; // 中间变量
for (int i = 0; i < size-1; i++) {
int k = i; // 待确定的位置
// 选择出应该在第i个位置的数
for (int j = size - 1; j > i; j--) {
if (numbers[j] < numbers[k]) {
k = j;
}
}
// 交换两个数
temp = numbers[i];
numbers[i] = numbers[k];
numbers[k] = temp;
}
}
取引所のO(N * n)のパフォーマンスより良いバブルソート少数の時間複雑
水と挿入ソートアルゴリズム
基本的な考え方:
すべての挿入ソート最後まで、各ステップは、レコードのソートとなり、コードサイズは単語のシーケンスの前に位置に挿入される順序は、(前にバックから右位置を見つけた後)にソートされています。
Java実装
public static void insertSort(int[] numbers) {
int size = numbers.length;
int temp = 0;
int j = 0;
for (int i = 1; i < size; i++) {
temp = numbers[i];
// 假如temp比前面的值小,则将前面的值后移
for (j = i; j > 0 && temp < numbers[j - 1]; j--) {
numbers[j] = numbers[j - 1];
}
numbers[j] = temp;
}
}
時の複雑さ
はO(n * n)はバブルソートと選択ソート優れた性能
四ディアンヒルソートアルゴリズム
基本的な考え方:
レコードの全体の配列は、いくつかのサブシーケンスに分割直接挿入ソート、すべてのレコードの直接挿入ソートのために順次、「実質的に規則的」である配列全体を記録する第一ソートする場合。
Java実装
/**
* 希尔排序的原理:根据需求,如果你想要结果从小到大排列,它会首先将数组进行分 组,然后将较小值移到前面,较大值
* 移到后面,最后将整个数组进行插入排序,这样比起一开始就用插入排序减少了数 据交换和移动的次数,
* 可以说希尔排序是加强 版的插入排序 拿数组5, 2,8, 9, 1, 3,4来说,数组长 度为7,当increment为3时,数组分为两个序列
* 5,2,8和9,1,3,4,第一次排序,9和5比较,1和2比较,3和8比较,4和比其 下标值小increment的数组值相比较
* 此例子是按照从小到大排列,所以小的会排在前面,第一次排序后数组为5, 1, 3, 4, 2, 8,9
* 第一次后increment的值变为3/2=1,此时对数组进行插入排序, 实现数组从大到 小排
*/
public static void shellSort(int[] data) {
int j = 0;
int temp = 0;
// 每次将步长缩短为原来的一半
for (int increment = data.length / 2; increment > 0; increme nt /= 2) {
for (int i = increment; i < data.length; i++) {
temp = data[i];
for (j = i; j >= increment; j -= increment) {
if (temp < data[j - increment])// 从小到大排
{
data[j] = data[j - increment];
} else {
break;
}
}
data[j] = temp;
}
}
ファイブディアンヒープソートアルゴリズム
基本的な考え方:
ヒープはソートツリー選択、ソート、ソート直接選択の向上に有効です。
スタック定義:配列を有するn個の要素(H1、H2、...、HN )、 場合に限り(HI> =伝送路特性がh21、HI> =伝送路特性がh21 + 1) 又は(HI <=伝送路特性がh21、HI < =伝送路特性がh21 + 1)(iは= 1,2、...、 N / 2と呼ばれるスタック)時間。私たちは、ヒープのかつての条件を満たしているだけで議論します。スタック要素(すなわち、最初の要素)の上部が最大用語(大スタックトップ)のためになり、スタックによって定義された見ることができます。完全なバイナリツリー構造を視覚的にスタック表現することができます。スタックのトップは、他のサブツリーの左、右のサブツリーに、ルートです。
思想:初期シーケンスは、2進数を発注する順次格納され、この時スタック、ルートノードの最大数のスタックを作り、それらの格納順序を調整するとみなされます。その後、為替のルートノードとヒープの最後。次に、前述の(N-1)がスタックにするために、再調整の数。ように、ヒープの2つのノードのみになるまで、彼らは交換を行い、最終的にはn個のノードのシーケンスを命じてきました。ビューのアルゴリズム点の記述から、ヒープの並べ替えは、2つのプロセスを必要とし、一方がヒープの確立であり、そして第二に、ヒープの最上部と最後の要素の交換位置をスタック。だから、ヒープの並べ替え、それは2つの機能を持っています。まず、ヒープ***機能を構築し、第二は、機能の並べ替えを達成するために***機能繰り返し呼び出されます。
Java実装
public static void heapSort(int[] a){
int arrayLength = a.length;
// 循环建堆
for (int i = 0; i < arrayLength - 1; i++) {
// 建堆
buildMaxHeap(a, arrayLength - 1 - i);
// 交换堆顶和最后一个元素
swap(a, 0, arrayLength - 1 - i);
System.out.println(Arrays.toString(a));
}
}
// 对data数组从0到lastIndex建大顶堆
public static void buildMaxHeap(int[] data, int lastIndex) {
// 从lastIndex处节点(最后一个节点)的父节点开始
for (int i = (lastIndex - 1) / 2; i >= 0; i--) {
// k保存正在判断的节点
int k = i;
// 如果当前k节点的子节点存在
while (k * 2 + 1 <= lastIndex) {
// k节点的左子节点的索引
int biggerIndex = 2 * k + 1;
// 如果biggerIndex小于lastIndex,即biggerIndex+1代表的k 节点的右子节点存在
if (biggerIndex < lastIndex) {
// 若果右子节点的值较大
if (data[biggerIndex] < data[biggerIndex + 1]) {
// biggerIndex总是记录较大子节点的索引
biggerIndex++;
}
}
// 如果k节点的值小于其较大的子节点的值
if (data[k] < data[biggerIndex]) {
// 交换他们
swap(data, k, biggerIndex);
// 将biggerIndex赋予k,开始while循环的下一次循环,重新 保证k节点的值大于其左右子节点的值
k = biggerIndex;
} else {
break;
}
}
}
}
// 交换
private static void swap(int[] data, int i, int j) {
int tmp = data[i];
data[i] = data[j];
data[j] = tmp;
}
シックス・ディアンは、高速なソートアルゴリズム
基本的な考え方:
キーの他の部分は、レコードのキー部分よりも小さいことを特徴とトリップレコードを注文することによって、二つの別々の部分に分類する、それぞれ配列決定する2つの部分が順序付けられたの配列全体まで続きます。
Java実装
/**
* 快速排序
*
* @param numbers
* 带排序数组
*/
public static void quick(int[] numbers) {
if (numbers.length > 0) // 查看数组是否为空
{
quickSort(numbers, 0, numbers.length - 1);
}
}
/**
*
* @param numbers
* 带排序数组
* @param low
* 开始位置
* @param high
* 结束位置
*/
public static void quickSort(int[] numbers, int low, int high) {
if (low >= high) {
return;
}
int middle = getMiddle(numbers, low, high); // 将numbers数组 进行一分为二
quickSort(numbers, low, middle - 1); // 对低字段表进行递归排序
quickSort(numbers, middle + 1, high); // 对高字段表进行递归排序
}
/**
* 查找出中轴(默认是最低位low)的在numbers数组排序后所在位置
*
* @param numbers
* 带查找数组
* @param low
* 开始位置
* @param high
* 结束位置
* @return 中轴所在位置
*/
public static int getMiddle(int[] numbers, int low, int high) {
int temp = numbers[low]; // 数组的第一个作为中轴
while (low < high) {
while (low < high && numbers[high] > temp) {
high--;
}
numbers[low] = numbers[high];// 比中轴小的记录移到低端
while (low < high && numbers[low] < temp) {
low++;
}
numbers[high] = numbers[low]; // 比中轴大的记录移到高端
}
numbers[low] = temp; // 中轴记录到尾
return low; // 返回中轴的位置
}
挿入ソート、それは全体的な効率を向上させることができるソート挿入を使用して、小さな配列要素に一般的であるようにクイックシーケンスのいくつかの要素は、効率が低くなります。
七ディアンマージソートアルゴリズム
基本的な考え方:
(マージ)をマージすることは、順序付けられたリストの新たなソートされたリスト内の各サブシーケンスが順序付けされるサブシーケンスの数、に分類される、すなわち配列2つ(またはそれ以上)の一種です。そして、順序付けられたシーケンスに全体のサブシーケンスを命じました。
Java実装
/**
* 归并排序
* 简介:将两个(或两个以上)有序表合并成一个新的有序表 即把待排序序列分为若 干个子序列,每个子序列是有序的。然后再把有序子序列合并为整体有序序列
* 时间复杂度为O(nlogn)
* 稳定排序方式
* @param nums 待排序数组
* @return 输出有序数组
*/
public static int[] sort(int[] nums, int low, int high) {
int mid = (low + high) / 2;
if (low < high) {
// 左边
sort(nums, low, mid);
// 右边
sort(nums, mid + 1, high);
// 左右归并
merge(nums, low, mid, high);
}
return nums;
}
/**
* 将数组中low到high位置的数进行排序
* @param nums 待排序数组
* @param low 待排的开始位置
* @param mid 待排中间位置
* @param high 待排结束位置
*/
public static void merge(int[] nums, int low, int mid, int high) {
int[] temp = new int[high - low + 1];
int i = low;// 左指针
int j = mid + 1;// 右指针
int k = 0;
// 把较小的数先移到新数组中 while (i <= mid && j <= high) {
if (nums[i] < nums[j]) {
temp[k++] = nums[i++];
} else {
temp[k++] = nums[j++];
}
}
// 把左边剩余的数移入数组
while (i <= mid) {
temp[k++] = nums[i++];
}
// 把右边边剩余的数移入数组
while (j <= high) {
temp[k++] = nums[j++];
}
// 把新数组中的数覆盖nums数组
for (int k2 = 0; k2 < temp.length; k2++) {
nums[k2 + low] = temp[k2];
}
}
性能比較時間アルゴリズムの複雑さと他の
GitHubのフォローアップ関連コンテンツの更新が、私はスターを歓迎し、見て、見ることができるインパクト金と銀3人の4人の小さなパートナーにしたい
(引か左GitHubのリンク、あなたは自分自身を見つけることができる、そのようなインタビューなどの関連コンテンツへのアクセスを必要とします)
https://github.com/xiangjiana/Android-MS
(VX:mm14525201314)