一区二区三区在线-一区二区三区亚洲视频-一区二区三区亚洲-一区二区三区午夜-一区二区三区四区在线视频-一区二区三区四区在线免费观看

服務器之家:專注于服務器技術及軟件下載分享
分類導航

PHP教程|ASP.NET教程|Java教程|ASP教程|編程技術|正則表達式|C/C++|IOS|C#|Swift|Android|VB|R語言|JavaScript|易語言|vb.net|

服務器之家 - 編程語言 - Java教程 - Java重點之基于比較的七大排序

Java重點之基于比較的七大排序

2022-02-10 14:59小玄ks Java教程

最近幾天在研究排序算法,看了很多博客,發現網上有的文章中對排序算法解釋的并不是很透徹,而且有很多代碼都是錯誤的,所以我根據這幾天看的文章,整理了一個較為完整的排序算法總結,本文中的所有算法均有JAVA實現,經

七大基于比較的排序

直接插入排序

思想:以雙指針來進行遍歷數組和尋找較小元素的操作,每次找到較小元素的時候就將其插入到前面的適當位置,當遍歷完整個數組,并完成插入操作后,排序完成。

時間復雜度:最好情況:O(N)
最壞情況:O(N^2)
空間復雜度:O(1)
結論:當一組數據趨近于有序,適用于插入排序

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
public static void insertSort(int[] array) {
        //該循環實現對整個數組的遍歷操作
        for (int i = 1; i < array.length; ++i) {
            
            //記錄將被插入的元素(i下標元素)
            int tmp = array[i];
            //j指向i的前一個元素
            int j = i - 1;
 
            for (; j >= 0; j--) {
                //如果j指向的元素比被插入元素大,就往后移一位
                if (array[j] > tmp) {
                    array[j + 1] = array[j];
                } else {//否則就找到了插入位置,跳出該循環
                    break;
                }
            }
 
            
            //j+1即為插入位置
            array[j + 1] = tmp;
        }
}

希爾排序

思想:將數組不斷分組再進行排序,當分組的長度為1時,進行的就是直接插入排序。

時間復雜度:O(N1.3 ~ N1.5)
空間復雜度:O(1)

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
public static void shellSort(int[] array) {
        int gap = array.length;
        while (gap > 1) {
            //gap為1時,就是直接插入排序
            gap = gap / 3 + 1;
            shell(array, gap);
        }
}
public static void shell(int[] array, int gap) {
        for (int i = gap; i < array.length; ++i) {
            int tmp = array[i];
            int j = i - gap;
            for (; j >= 0; j -= gap) {
                if (array[j] > tmp) {
                    array[j + gap] = array[j];
                } else {
                    break;
                }
            }
            array[j + gap] = tmp;
        }
}

選擇排序

思想:選擇排序是一種簡單直觀的排序算法。它的工作原理是:第一次從待排序的數據元素中選出最小(或最大)的一個元素,存放在序列的起始位置,然后再從剩余的未排序元素中尋找到最?。ù螅┰?,繼續放在起始位置直到未排序元素個數為0。

時間復雜度:O(N2)

空間復雜度:O(N2)

?
1
2
3
4
5
6
7
8
9
10
11
public static void selectSort(int[] array){
    for(int i = 0;i<array.length;++i){
        for(int j = i+1;j<array.length;++j){
            if(array[j]<array[i]){
                int tmp = array[i];
                array[i] = array[j];
                array[j] = tmp;
            }
        }
    }
}

堆排序

思想:從小到大排序,就先建一個大堆,堆頭元素就是整個數組中最大的數,==因此我們每次將堆頭元素與堆尾元素交換,交換一次,堆尾下標往前移動一位,形成一個新堆,再向下調整構建成大堆;==以此循環,直到堆尾下標與堆頭下標重合,堆排序完成。

時間復雜度:O(N*log N)

空間復雜度:O(1)

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
public static void heapSort(int[] array) {
        createHeap(array);//建大堆
        int end = array.length - 1;
    //將堆頭元素與堆尾元素互換位置,就將最大元素放到了最后一位,舍去最后一位小標重新將堆向下調整;直到堆為空,數組中元素就排序完成。
        while (end >= 0) {
            int tmp = array[0];
            array[0] = array[end];
            array[end] = tmp;
            end--;
            siftDown(array, 0, end);
        }
    }
    //從小到大排序,建一個大堆
    public static void createHeap(int[] array) {
        for (int parent = (array.length - 1) / 2; parent >= 0; parent--) {
            siftDown(array, parent, array.length-1);
        }
    }
 
    //向下調整大堆
    public static void siftDown(int[] array, int root, int end) {
        int parent = root;
        int child = 2 * parent + 1;
        while (child <= end) {
            if (child + 1 <= end && array[child] < array[child + 1])
                child++;
            if (array[parent] < array[child]) {
                int tmp = array[parent];
                array[parent] = array[child];
                array[child] = tmp;
                parent = child;
                child = parent * 2 + 1;
            } else {
                break;
            }
        }
    }

冒泡排序

思想:相鄰的元素兩兩比較,較大的數下沉,較小的數冒起來,這樣一趟比較下來,最大(小)值就會排列在一端。該冒泡排序為優化過的排序,定義一個boolean類型的變量來判斷數組是否已經有序,若有序可以直接返回,以此來減少時間復雜度。

時間復雜度:最壞:O(N2)

? 最優:O(N)

空間復雜度:O(1)

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
public static void bubbleSort(int[] array) {
    //最外層循環為比較的趟數
       for (int i = 0; i < array.length - 1; ++i) {
           //flag是為了判斷接下來的循環是否有必要進行
           boolean flag = false;
           //內層循環為每趟比較的次數
           for (int j = 0; j < array.length - 1 - i; ++j) {
               if (array[j] > array[j + 1]) {
                   int tmp = array[j];
                   array[j] = array[j + 1];
                   array[j + 1] = tmp;
                   flag = true;
               }
           }
           //flag==false說明這趟循環沒有交換數據,也就是說數組已經有序,可以直接返回。
           if (flag == false) return;
 
       }
   }

快速排序

思想:先找到一個中間元素,將小于這個元素的數放到它的左邊,大于這個元素的數放到它的右邊,再將左右兩部分進行上述操作,重復以往,就完成快排操作。
時間復雜度:最好:O(Nlog 2N)
最壞:O(N2)
時間復雜度平均:O(Nlog2N)
空間復雜度:O(Nlog2N)

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
public static void quickSort(int[] array, int l, int r) {
        if (l >= r) return;
    //因為用do while()循環,所以先將左右指針向兩邊移動一位
        int i = l - 1, j = r + 1;
    //取數組中間元素的值作為這個分割點
        int mid = array[(l + r)>>1];
 
        while (i < j) {
            //左邊的數小于中間值,指針向右移動
            do ++i; while (array[i] < mid);
            //右邊的數大于中間值,指針向左移動
            do --j; while (array[j] > mid);
            //兩個指針停下后交換元素
            if (i < j) {
                int tmp = array[i];
                array[i] = array[j];
                array[j] = tmp;
            }
 
        }
    //遞歸左半部分
        quickSort(array, l, j);
    //遞歸右半部分
        quickSort(array, j + 1, r);
 
 
    }

歸并排序

思想:先分組再排序,和快排操作順序相反。將數組分為左右兩部分,再對左右兩部分 分別再分組,以此類推,直到每一部分只有一個元素,然后按順序合并為一個個新的有序數組,小數組歸并為大數組,以此類推就得到排序后的數組。

時間復雜度:O(N*logN)

空間復雜度:O(N)

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
public static void mergeSort(int[] array){
       mergerSortInternal(array,0,array.length-1);
   }
   public static void mergerSortInternal (int[] array,int l,int r){
       if(l>=r)    return;
       int mid = (l+r)>>1;
       //遞歸左半部分
       mergerSortInternal(array,l,mid);
       //遞歸右半部分
       mergerSortInternal(array,mid+1,r);
       //歸并
       merge(array,l,mid,r);
   }
   public static void merge(int[] array,int l,int mid, int r){
       int s1 = l,e1 = mid;
       int s2 = mid+1, e2 = r;
       int [] tmp = new int[r-l+1];
       int k = 0;
       //比較兩個有序小數組元素,將小的元素放到新數組前面,大的元素放到新數組后面
       while(s1<=e1 && s2<=e2){
           if(array[s1]<array[s2]){
               tmp[k++] = array[s1++];
           }else{
               tmp[k++] = array[s2++];
           }
       }
       //處理剩余元素
       while(s1<=e1)   tmp[k++] = array[s1++];
       while(s2<=e2)   tmp[k++] = array[s2++];
       //將排完序的新數組元素放回原數組中
       for(int i = 0;i<tmp.length;++i){
           array[i+l] = tmp[i];
       }
   }

到此這篇關于Java重點之基于比較的七大排序的文章就介紹到這了,更多相關Java 排序內容請搜索服務器之家以前的文章或繼續瀏覽下面的相關文章希望大家以后多多支持服務器之家!

原文鏈接:https://blog.csdn.net/m0_52373742/article/details/120406634

延伸 · 閱讀

精彩推薦
主站蜘蛛池模板: 色婷丁香 | 亚洲精品一二区 | 亚洲免费闲人蜜桃 | 韩国三级在线播放 | 91精品国产91久久久久久麻豆 | 男人天堂影院 | 精品国产免费久久久久久 | 国产精品国产香蕉在线观看网 | 高清欧美videossexo免费 | 国产午夜一区二区在线观看 | 99久精品 | 好男人在线观看hd中字 | 久久水蜜桃亚洲AV无码精品偷窥 | 欧美成人禁片在线观看俄罗斯 | 欧美日韩一区二区三区免费 | 毛片一区二区三区提莫影院 | 亚洲精品一区制服丝袜 | 91高清国产经典在线观看 | 国产精品成人网红女主播 | 麻豆小视频在线观看 | 精品国产免费久久久久久 | 国产色站 | 国产精品亚洲一区二区 | ady成人映画网站官网 | 日韩毛片高清在线看 | 2020精品极品国产色在线观看 | 韩国禁片在线观看久 | 国产成人高清精品免费观看 | 国产精品美女久久久久 | 91国语自产拍在线观看 | 免费观看一级欧美在线视频 | hezyo加勒比一区二区三区 | 538亚洲欧美国产日韩在线精品 | 久久久伊人影院 | 无遮掩60分钟从头啪到尾 | 亚洲精品一区二区观看 | 国产精品免费看久久久香蕉 | 国产成人亚洲综合91精品555 | 男同精品视频免费观看网站 | 精品无人区麻豆乱码无限制 | 成人性生交小说免费看 |