過去を振り返ることで新しいことを学ぶことができます。並べ替えアルゴリズムは難しくありません。通常は並べ替えます。Javaには並べ替えアルゴリズムが付属しています。コレクションに付属する並べ替えアルゴリズムと同様に、基盤となる実装はマージ並べ替えとバイナリツリー並べ替えです。それをチェックすることができます。
一般的な並べ替えアルゴリズムについて説明しましょう。特に難解ではありません。コードを記述して、アルゴリズムのアイデアと実装を確認してください。
1.バブルソート、
これについては話しません。コードに移動するだけです。最初にアルゴリズムに触れたときに学びました。
/**
* 冒泡排序
* 时间复杂度O(n*n)
* @param list
* @return
*/
public static List<Integer> sortByBob(List<Integer> list){
if(list.isEmpty()){
return new ArrayList<>();
}
int length = list.size();
for (int i = 0; i < list.size(); i++) {
for (int j = 0; j < length-1-i; j++) {
if(list.get(j)>list.get(j+1)){
int temp = list.get(j);
list.set(j,list.get(j+1));
list.set(j+1,temp);
}
}
}
System.out.println(JSONArray.toJSONString(list));
return list;
}
2.並べ替えを選択します
選択ソート、わかりやすいと思いますが、いつもバブルソートだと思っていたのですが、比較なのでアルゴリズムの複雑さもO(n * n)なので、誰もが理解しやすいです、通常、使用するにはコストがかかりすぎ、費用対効果が高くないことはめったにありません。コードを見てみましょう。
/**
* 选择排序,和冒泡排序时间复杂度一样,更容易理解
* 时间复杂度O(n*n)
* @param list
* @return
*/
public static List<Integer> sortByChoose(List<Integer> list){
if(list.isEmpty()){
return new ArrayList<>();
}
for (int i = 0; i < list.size(); i++) {
for (int j = i+1; j < list.size(); j++) {
if(list.get(i)>list.get(j)){
int temp = list.get(i);
list.set(i,list.get(j));
list.set(j,temp);
}
}
}
System.out.println(JSONArray.toJSONString(list));
return list;
}
3.挿入ソート
これも基本的なソートであり、バブルソートよりもパフォーマンスが低いように感じますが、最悪の場合、時間計算量もO(n * n)です。通常、デフォルトの挿入ソートの時間計算量はO( n * n)、この男は注意を払い、コードを見てください。
/**
* 插入排序
* 插入排序思想容易理解,写起来比较绕,就是把j位置上的值往前一位设置,判断当前的数据小于某一位时,停止复制,
* 把预存的i位置的值赋上去
* 这个感觉时间复杂度比冒泡少,但是实际上平均时间复杂度是n^2/4+n/2-1/2,最差的结果也是n^2
* @param list
* @return
*/
static public List<Integer> sortByInsert(List<Integer> list){
for (int i = 1; i < list.size(); i++) {
int j ;
if(list.get(i-1)>list.get(i)){
int temp = list.get(i);
for (j = i-1;j>=0&&temp<list.get(j);j--){
list.set(j+1,list.get(j));
}
list.set(j+1,temp);
}
}
System.out.println(JSONArray.toJSONString(list));
return list ;
}
4.クイックソート
クイックソートは区分的に再帰的なアイデアであり、比較的成熟したソートアルゴリズムであるnlogNの時間計算量があります。さて、コードを見てください。
/**
* 快速排序
* (1)首先设定一个分界值,通过该分界值将数组分成左右两部分。 [2]
* (2)将大于或等于分界值的数据集中到数组右边,小于分界值的数据集中到数组的左边。此时,左边部分中各元素都小于或等于分界值,而右边部分中各元素都大于或等于分界值。
* (3)然后,左边和右边的数据可以独立排序。对于左侧的数组数据,又可以取一个分界值,将该部分数据分成左右两部分,同样在左边放置较小值,右边放置较大值。右侧的数组数据也可以做类似处理。
* (4)重复上述过程,可以看出,这是一个递归定义。通过递归将左侧部分排好序后,再递归排好右侧部分的顺序。当左、右两个部分各数据排序完成后,整个数组的排序也就完成了。
* @return
*/
public static List<Integer> quickSort(List<Integer> list,Integer start,Integer end){
if (list.isEmpty()) return new ArrayList<>();
int i = start;
int j = end;
int mark = list.get(start);
while (i<j){
while ((i<j)&&list.get(j)>mark){
j--;
}
while ((i<j)&&(list.get(i)<mark)){
i++;
}
if((list.get(i)==list.get(j))&&i<j){
i++;
}else {
int temp = list.get(i);
list.set(i,list.get(j));
list.set(j,temp);
}
}
if(i-1>start) list = quickSort(list,start,i-1);
if(j+1<end) list = quickSort(list,j+1,end);
return list;
}
5.マージして並べ替え
このソートアルゴリズムは、私たちの使用法に比較的近いと言えます。また、マージソートはセットソートで使用されると述べました。さらに、MYSQLのソートもマージソートです。マージソートは理解しやすく効率的ですが、より多くのメモリを消費しますが、この消費はほとんどのシステムで許容されます。コードを見てください。
/**
* 归并排序递归
* @param list
* @param left
* @param right
* @return
*/
public static List<Integer> mergeSort(List<Integer> list,int left,int right){
if(left<right){
int mid = (left+right)/2;
mergeSort(list,left,mid);
mergeSort(list,mid+1,right);
mergePlatfrom(list,left,mid,right);
}
return list;
}
/**
* 归并排序是底层实现
* @param list
* @param left
* @param mid
* @param right
*/
static public void mergePlatfrom(List<Integer> list,int left,int mid,int right){
List<Integer> temp = new ArrayList<>(); //存放排序后的新队列
int i = left;
int j = mid+1;
int t = 0;
while (i<=mid && j<=right){ //归并会从中间分开,从两侧依次拿出一个数据进行对比,然后放到新数据集合里面,这样新的数据集合里面的数据就是有序的
if(list.get(i)<=list.get(j)){
temp.add(list.get(i++));
} else {
temp.add(list.get(j++));
}
}
//表示左侧的数据很大,右侧的数据已经比完了,左侧还有多个数据,因为默认是有序的(会递归),所以直接放进新的数据集合里
while (i<=mid){
temp.add(list.get(i++));
}
//同理,表示右侧的数据很大,左侧的数据已经比完了,右侧还有多个数据,默认有序(会递归),也直接放进新的数据集合里
while (j<=right){
temp.add(list.get(j++));
}
//把排序后的新的数据集合放到原来的数据集合里面
t = 0;
while (left <= right){
list.set(left++,temp.get(t++));
}
}
コードは特に古典的ではありませんが、かなり単純で理解しやすく、アルゴリズムのメインロジックを実装しています。ソートアルゴリズムを確認したい友達はそれをチェックすることができます。
犠牲も勝利もありません〜