成人免费xxxxx在线视频软件_久久精品久久久_亚洲国产精品久久久_天天色天天色_亚洲人成一区_欧美一级欧美三级在线观看

程序員必須掌握這幾種排序算法的優(yōu)秀實(shí)踐,包會(huì)!(含GIF圖)

開(kāi)發(fā) 后端
由于排序通常有助于降低問(wèn)題的算法復(fù)雜性,因此它在計(jì)算機(jī)科學(xué)中具有重要用途。百度搜索顯示,當(dāng)今計(jì)算世界中有 40 多種不同的排序算法。瘋狂吧?那你知道幾個(gè)呢!

排序是計(jì)算機(jī)中常見(jiàn)且重要的操作,用于使數(shù)據(jù)按照某種規(guī)則或標(biāo)準(zhǔn)進(jìn)行有序化,便于后續(xù)的搜索、查找和處理。

為什么排序算法很重要?

由于排序通常有助于降低問(wèn)題的算法復(fù)雜性,因此它在計(jì)算機(jī)科學(xué)中具有重要用途。百度搜索顯示,當(dāng)今計(jì)算世界中有 40 多種不同的排序算法。瘋狂吧?那你知道幾個(gè)呢!

現(xiàn)實(shí)世界中實(shí)現(xiàn)這一點(diǎn)的一些最佳示例是。

  • 冒泡排序用于電視節(jié)目中,根據(jù)觀眾觀看時(shí)間對(duì)頻道進(jìn)行排序!
  • 數(shù)據(jù)庫(kù)使用外部合并排序?qū)μ蠖鵁o(wú)法完全加載到內(nèi)存中的數(shù)據(jù)集進(jìn)行排序!
  • 體育比分通過(guò)快速排序算法實(shí)時(shí)快速組織!

數(shù)據(jù)結(jié)構(gòu)中的排序類型

  • 基于比較的排序:在基于比較的排序技術(shù)中,定義比較器來(lái)比較數(shù)據(jù)樣本的元素或項(xiàng)目。該比較器定義元素的順序。例子有:冒泡排序、歸并排序。
  • 基于計(jì)數(shù)的排序:這些類型的排序算法中的元素之間不涉及比較,而是在執(zhí)行過(guò)程中進(jìn)行計(jì)算假設(shè)。例如:計(jì)數(shù)排序、基數(shù)排序。
  • 就地與非就地排序(In-Place vs Not-in-Place Sorting):數(shù)據(jù)結(jié)構(gòu)中的就地排序技術(shù)會(huì)修改原始數(shù)組中數(shù)組元素的順序。另一方面,非就地排序技術(shù)使用輔助數(shù)據(jù)結(jié)構(gòu)對(duì)原始數(shù)組進(jìn)行排序。就地排序技術(shù)的示例有:冒泡排序、選擇排序。非就地排序算法的一些示例包括:合并排序、快速排序。
下面詳細(xì)介紹一下,8 種排序算法。

PS:GIF圖較大,耐心等待打開(kāi),值得反復(fù)去看!

1、冒泡排序

冒泡排序的基本思想是,如果相鄰元素的順序不符合要求,則重復(fù)交換相鄰元素。是的,就是這么簡(jiǎn)單。

如果給定的數(shù)組元素必須按升序排序,則冒泡排序?qū)⑹紫缺容^數(shù)組的第一個(gè)元素與第二個(gè)元素,如果結(jié)果大于第二個(gè)元素,則立即交換它們,然后繼續(xù)比較第二個(gè)和第三個(gè)元素,依此類推。

通過(guò)一個(gè)簡(jiǎn)單的例子理解冒泡排序算法。

讓我們嘗試通過(guò)一個(gè)例子來(lái)理解冒泡排序背后的直觀方法:

冒泡排序算法解釋

Java 中的實(shí)現(xiàn)

import java.util.Arrays;

public class BubbleSort {
    public static void bubbleSort(int[] arr) {
        int n = arr.length;
        for (int i = 0; i < n - 1; i++) {
            for (int j = 0; j < n - i - 1; j++) {
                if (arr[j] > arr[j + 1]) {
                    int temp = arr[j];
                    arr[j] = arr[j + 1];
                    arr[j + 1] = temp;
                }
            }
        }
    }

    public static void main(String[] args) {
        int[] arr = {5, 3, 4, 2, 1};
        bubbleSort(arr);
        System.out.println("Sorted array: ");
        for (int num : arr) {
            System.out.print(num + " ");
        }
        System.out.println();
    }
}

冒泡排序的實(shí)現(xiàn)

時(shí)間復(fù)雜度:

  • 最壞情況: O(n^2)
  • 平均情況:O(n*logn)
  • 最好的情況:O(n*logn)

空間復(fù)雜度: O(1)。

2、選擇排序

選擇排序是一種排序算法,其中給定數(shù)組分為兩個(gè)子數(shù)組:已排序的左部分和未排序的右部分。

最初,已排序部分為空,未排序部分是整個(gè)列表。在每次迭代中,我們從未排序列表中獲取最小元素并將其推送到已排序列表的末尾,從而構(gòu)建已排序的數(shù)組。

通過(guò)示例了解選擇排序算法。

讓我們嘗試用一個(gè)簡(jiǎn)單的例子來(lái)理解選擇排序背后的直觀想法:

選擇排序算法解釋

Java 中的實(shí)現(xiàn)

import java.util.Arrays;

public class SelectionSort {
    public static void selectionSort(int[] arr) {
        int n = arr.length;
        for (int i = 0; i < n - 1; i++) {
            int minIndex = i;
            for (int j = i + 1; j < n; j++) {
                if (arr[j] < arr[minIndex]) {
                    minIndex = j;
                }
            }
            int temp = arr[minIndex];
            arr[minIndex] = arr[i];
            arr[i] = temp;
        }
    }

    public static void main(String[] args) {
        int[] arr = {25, 22, 27, 15, 19};
        selectionSort(arr);
        System.out.println("Sorted array:");
        for (int num : arr) {
            System.out.print(num + " ");
        }
        System.out.println();
    }
}

選擇排序的實(shí)現(xiàn)

時(shí)間復(fù)雜度:

  • 最壞情況: O(n*n)
  • 平均情況: O(n*logn)
  • 最好情況: O(n*logn)

空間復(fù)雜度: O(1)。

3、插入排序

插入排序是一種將給定數(shù)組分為已排序部分和未排序部分的排序算法。在每次迭代中,要插入的元素必須在已排序的子序列中找到其最佳位置,然后插入,同時(shí)將剩余元素向右移動(dòng)。

通過(guò)示例了解插入排序算法。

下面是一個(gè)例子,可以幫助更好地理解插入排序:

插入排序算法解釋

現(xiàn)在已經(jīng)了解了插入排序的實(shí)際工作原理,接下來(lái)看一下 Java的 實(shí)現(xiàn)。

import java.util.Arrays;

public class InsertionSort {
    public static void insertionSort(int[] arr) {
        int n = arr.length;
        for (int i = 1; i < n; i++) {
            int key = arr[i];
            int j = i - 1;
            while (j >= 0 && arr[j] > key) {
                arr[j + 1] = arr[j];
                j = j - 1;
            }
            arr[j + 1] = key;
        }
    }

    public static void main(String[] args) {
        int[] arr = {25, 22, 27, 15, 19};
        insertionSort(arr);
        System.out.println(Arrays.toString(arr));
    }
}

插入排序的實(shí)現(xiàn)

時(shí)間復(fù)雜度:

  • 最壞情況: O(n*n)
  • 平均情況: O(n*logn)
  • 最好情況: O(n*logn)

空間復(fù)雜度: O(1)。

4、快速排序

快速排序是一種分而治之的算法。快速排序背后的直觀概念是,它從給定的元素?cái)?shù)組中選擇一個(gè)元素作為主元,然后圍繞主元元素對(duì)數(shù)組進(jìn)行分區(qū)。隨后,它遞歸地調(diào)用自身并隨后對(duì)兩個(gè)子數(shù)組進(jìn)行分區(qū)。

通過(guò)可視化了解快速排序算法。

快速排序算法涉及的邏輯步驟如下:

  • 樞軸選擇:選擇一個(gè)元素作為樞軸(這里,我們選擇最后一個(gè)元素作為樞軸)。
  • 分區(qū):數(shù)組的分區(qū)方式使得所有小于主元的元素都位于左子數(shù)組中,而所有嚴(yán)格大于主元的元素都存儲(chǔ)在右子數(shù)組中。
  • 遞歸調(diào)用快速排序:對(duì)上面創(chuàng)建的兩個(gè)子數(shù)組再次調(diào)用快速排序函數(shù),并重復(fù)步驟。

下面的實(shí)現(xiàn)中包含了注釋,以幫助更好地理解快速排序算法。

import java.util.Arrays;

public class QuickSort {
    
    public static int partition(int[] arr, int low, int high) {
        int pivot = arr[high];
        int i = low - 1;
        
        for (int j = low; j <= high - 1; j++) {
            if (arr[j] < pivot) {
                i++;
                swap(arr, i, j);
            }
        }
        
        swap(arr, i + 1, high);
        return i + 1;
    }
    
    public static void quickSort(int[] arr, int low, int high) {
        if (low < high) {
            int partitionIndex = partition(arr, low, high);
            
            quickSort(arr, low, partitionIndex - 1);
            quickSort(arr, partitionIndex + 1, high);
        }
    }
    
    public static void swap(int[] arr, int i, int j) {
        int temp = arr[i];
        arr[i] = arr[j];
        arr[j] = temp;
    }
    
    public static void main(String[] args) {
        int[] arr = {14, 21, 5, 2, 3, 19};
        int n = arr.length;
        
        quickSort(arr, 0, n - 1);
        
        System.out.print("Sorted array: ");
        for (int i = 0; i < n; i++) {
            System.out.print(arr[i] + " ");
        }
    }
}

快速排序的實(shí)現(xiàn)

時(shí)間復(fù)雜度:

  • 最壞情況: O(n*n)
  • 平均情況: O(n*logn)
  • 最好情況: O(n*logn)

空間復(fù)雜度: O(1)。

5、隨機(jī)快速排序

隨機(jī)快速排序與快速排序的區(qū)別:

快速排序是一種分治算法,通過(guò)選擇一個(gè)基準(zhǔn)元素(通常是數(shù)組中的一個(gè)元素),將數(shù)組劃分為兩個(gè)子數(shù)組,一個(gè)子數(shù)組中的所有元素都小于基準(zhǔn)元素,另一個(gè)子數(shù)組中的所有元素都大于基準(zhǔn)元素。然后遞歸地對(duì)這兩個(gè)子數(shù)組進(jìn)行排序。快速排序的平均時(shí)間復(fù)雜度為O(nlogn)。

隨機(jī)快速排序與快速排序的不同之處在于選擇基準(zhǔn)元素的方式。在快速排序中,通常選擇數(shù)組的第一個(gè)或最后一個(gè)元素作為基準(zhǔn)元素。而在隨機(jī)快速排序中,首先從數(shù)組中隨機(jī)選擇一個(gè)元素作為基準(zhǔn)元素,然后進(jìn)行劃分。

隨機(jī)快速排序的主要優(yōu)點(diǎn)是減少了快速排序中最壞情況出現(xiàn)的概率。在快速排序中,如果選擇的基準(zhǔn)元素是數(shù)組中的最小或最大元素,或者數(shù)組已經(jīng)是有序的,那么劃分結(jié)果可能會(huì)非常不平衡,導(dǎo)致算法的時(shí)間復(fù)雜度接近O(n^2)。通過(guò)隨機(jī)選擇基準(zhǔn)元素,可以有效地降低這種情況發(fā)生的概率,提高算法的平均性能。

因此,隨機(jī)快速排序相對(duì)于快速排序來(lái)說(shuō),具有更好的性能保證,尤其是在面對(duì)特定情況下的輸入數(shù)據(jù)時(shí)。它在實(shí)踐中通常被認(rèn)為是快速排序的一種優(yōu)化版本,可以提供更一致的性能,并減少最壞情況的發(fā)生概率。

時(shí)間復(fù)雜度:

  • 最壞情況: O(n*n)
  • 平均情況: O(n*logn)
  • 最好情況: O(n*logn)

空間復(fù)雜度: O(logn)。

6、歸并排序

歸并排序是一種分而治之的算法。在每次迭代中,歸并排序?qū)⑤斎霐?shù)組劃分為兩個(gè)相等的子數(shù)組,為這兩個(gè)子數(shù)組遞歸地調(diào)用自身,最后合并已排序的兩半。

通過(guò)可視化了解合并排序算法。

歸并排序算法解釋

看一下它的實(shí)現(xiàn)。

import java.util.Arrays;

public class MergeSort {

    public static void merge(long[] arr, long lt, long m, long rt) {
        long n1 = m - lt + 1;
        long n2 = rt - m;
        long[] L = new long[(int) n1];
        long[] R = new long[(int) n2];

        for (int i = 0; i < n1; i++)
            L[i] = arr[(int) (lt + i)];
        for (int j = 0; j < n2; j++)
            R[j] = arr[(int) (m + 1 + j)];

        int i = 0, j = 0;
        int k = (int) lt;
        while (i < n1 && j < n2) {
            if (L[i] <= R[j]) {
                arr[k] = L[i];
                i++;
            } else {
                arr[k] = R[j];
                j++;
            }
            k++;
        }

        while (i < n1) {
            arr[k] = L[i];
            i++;
            k++;
        }

        while (j < n2) {
            arr[k] = R[j];
            j++;
            k++;
        }
    }

    public static void mergeSort(long[] arr, long lt, long rt) {
        if (lt >= rt)
            return;

        long m = lt + (rt - lt) / 2;
        mergeSort(arr, lt, m);
        mergeSort(arr, m + 1, rt);
        merge(arr, lt, m, rt);
    }

    public static void printArray(long[] arr) {
        for (int i = 0; i < arr.length; i++)
            System.out.print(arr[i] + " ");
    }

    public static void main(String[] args) {
        long[] arr = {16, 19, 14, 20, 12, 13};
        System.out.print("Unsorted array is: ");
        printArray(arr);
        mergeSort(arr, 0, arr.length - 1);
        System.out.print("\nSorted array is: ");
        printArray(arr);
    }
}

歸并排序的實(shí)現(xiàn)

時(shí)間復(fù)雜度:

  • 最壞情況: O(n*logn)
  • 平均情況: O(n*logn)
  • 最好情況: O(n*logn)

空間復(fù)雜度: O(n)。

7、計(jì)數(shù)排序

計(jì)數(shù)排序是一種有趣的排序技術(shù),主要是因?yàn)樗P(guān)注特定范圍內(nèi)唯一元素的頻率(類似于散列)。

它的工作原理是計(jì)算具有不同鍵值的元素?cái)?shù)量,然后在計(jì)算未排序序列中每個(gè)唯一元素的位置后構(gòu)建排序數(shù)組。

它與上面列出的算法不同,因?yàn)樗鼘?shí)際上涉及輸入數(shù)據(jù)元素之間的零比較!

通過(guò)示例了解計(jì)數(shù)排序算法。

計(jì)數(shù)排序算法解釋

現(xiàn)在繼續(xù)看一下它在 Java 中的實(shí)現(xiàn)。

import java.util.Scanner;

public class CountSort {
   public static void print(long[] vec, long n) {
      for (long i = 1; i <= n; i++)
         System.out.print(vec[(int) i] + " ");
      System.out.println();
   }

   public static long getMax(long[] vec, long n) {
      long max = vec[1];
      for (long i = 2; i <= n; i++) {
         if (vec[(int) i] > max)
            max = vec[(int) i];
      }
      return max;
   }

   public static void countSort(long[] vec, long n) {
      long[] output = new long[(int) (n + 1)];
      long max = getMax(vec, n);
      long[] count = new long[(int) (max + 1)];
      for (int i = 0; i <= max; i++)
         count[i] = 0;
      for (long i = 1; i <= n; i++)
         count[(int) vec[(int) i]]++;
      for (int i = 1; i <= max; i++)
         count[i] += count[i - 1];
      for (long i = n; i >= 1; i--) {
         output[(int) count[(int) vec[(int) i]]] = vec[(int) i];
         count[(int) vec[(int) i]] -= 1;
      }
      for (long i = 1; i <= n; i++) {
         vec[(int) i] = output[(int) i];
      }
   }

   public static void main(String[] args) {
      Scanner scanner = new Scanner(System.in);
      System.out.print("Enter the size of array: ");
      long n = scanner.nextLong();
      long[] arr = new long[(int) (n + 1)];
      System.out.println("Enter elements:");
      for (long i = 1; i <= n; i++)
         arr[(int) i] = scanner.nextLong();
      System.out.print("Unsorted array: ");
      print(arr, n);
      countSort(arr, n);
      System.out.print("Sorted array: ");
      print(arr, n);
      scanner.close();
   }
}

計(jì)數(shù)排序?qū)崿F(xiàn)


時(shí)間復(fù)雜度:

  • 最壞情況: O(n+k),其中 n 是輸入數(shù)組的大小,k 是數(shù)組中唯一元素的數(shù)量。

空間復(fù)雜度: O(n+k)。

8、基數(shù)排序

正如之前所看到的,計(jì)數(shù)排序之所以與眾不同,是因?yàn)樗皇窍窈喜⑴判蚧蛎芭菖判蚰菢踊诒容^的排序算法,從而將其時(shí)間復(fù)雜度降低到線性時(shí)間。

但是,如果輸入數(shù)組的范圍從 1 到 n^2,計(jì)數(shù)排序就會(huì)失敗,在這種情況下,其時(shí)間復(fù)雜度會(huì)增加到 O(n^2)。

基數(shù)排序背后的基本思想是擴(kuò)展計(jì)數(shù)排序的功能,以便在輸入數(shù)組元素范圍從 1 到 n^2 時(shí)獲得更好的時(shí)間復(fù)雜度。

通過(guò)示例了解基數(shù)排序。

算法:

對(duì)于每個(gè)數(shù)字 i,其中 i 從數(shù)字的最低有效數(shù)字到最高有效數(shù)字變化,根據(jù)第 i 個(gè)數(shù)字使用計(jì)數(shù)排序算法對(duì)輸入數(shù)組進(jìn)行排序。請(qǐng)記住,我們使用計(jì)數(shù)排序,因?yàn)樗且环N穩(wěn)定的排序算法。

例子:

基數(shù)排序算法解釋

因此,我們觀察到基數(shù)排序在整個(gè)執(zhí)行過(guò)程中使用計(jì)數(shù)排序作為其子例程。現(xiàn)在看一下它的 Java實(shí)現(xiàn)。

import java.util.Arrays;

public class RadixSort {

    public static void getMax(long[] vec, int n) {
        long maxval = vec[0];
        for (int i = 1; i < n; i++) {
            if (vec[i] > maxval) {
                maxval = vec[i];
            }
        }
    }

    public static void countSort(long[] vec, int n, long x) {
        long[] res = new long[n];
        long[] count = new long[10];
        Arrays.fill(count, 0);

        for (int i = 0; i < n; i++) {
            count[(int)((vec[i] / x) % 10)]++;
        }

        for (int i = 1; i < 10; i++) {
            count[i] += count[i - 1];
        }

        for (int i = n - 1; i >= 0; i--) {
            res[(int)(count[(int)((vec[i] / x) % 10)] - 1)] = vec[i];
            count[(int)((vec[i] / x) % 10)]--;
        }

        for (int i = 0; i < n; i++) {
            vec[i] = res[i];
        }
    }

    public static void radixSort(long[] vec, int n) {
        long m = vec[0];
        for (int i = 1; i < n; i++) {
            if (vec[i] > m) {
                m = vec[i];
            }
        }

        for (long x = 1; m / x > 0; x *= 10) {
            countSort(vec, n, x);
        }
    }

    public static void main(String[] args) {
        long[] vec = { 53, 89, 150, 36, 633, 233 };
        int n = vec.length;
        radixSort(vec, n);
        for (int i = 0; i < n; i++) {
            System.out.print(vec[i] + " ");
        }
    }
}

基數(shù)排序?qū)崿F(xiàn)

時(shí)間復(fù)雜度: O(d(n+b)),其中b代表數(shù)組元素的基數(shù)(例如- 10代表十進(jìn)制)

空間復(fù)雜度: O(n+d),其中 d 是數(shù)組元素中的最大位數(shù)。

總結(jié)

排序算法總結(jié)

名詞解釋:

  • n:數(shù)據(jù)規(guī)模
  • k:“桶”的個(gè)數(shù)
  • In-place:占用常數(shù)內(nèi)存,不占用額外內(nèi)存
  • Out-place:占用額外內(nèi)存
  • 穩(wěn)定性:排序后 2 個(gè)相等鍵值的順序和排序之前它們的順序相同
責(zé)任編輯:姜華 來(lái)源: 今日頭條
相關(guān)推薦

2023-10-12 18:00:34

Git系統(tǒng)命令

2017-12-06 10:43:51

程序員軟技能

2018-07-02 10:15:11

Java程序員注解

2018-08-24 20:57:55

程序員編程語(yǔ)言Python

2021-11-10 09:17:18

程序員排序算法搜索算法

2023-02-09 07:39:01

2021-09-04 23:40:53

算法程序員前端

2022-09-24 09:03:55

前端單元測(cè)試冒泡排序

2021-02-24 09:26:03

JavaGC程序員

2012-08-20 09:26:17

程序員算法排列算法

2022-08-10 14:51:33

開(kāi)源Java工具

2023-09-12 11:25:15

2017-11-14 21:30:15

2013-07-09 15:26:29

程序員算法

2020-04-24 09:26:30

Java程序員工具

2011-05-24 17:20:57

程序員

2019-08-16 11:16:25

Java程序員流程圖

2019-08-26 10:00:49

程序員軟件技術(shù)

2014-08-29 11:09:44

程序員

2009-07-03 16:07:58

點(diǎn)贊
收藏

51CTO技術(shù)棧公眾號(hào)

主站蜘蛛池模板: 日韩欧美一区二区三区免费观看 | 国产乱码精品一品二品 | 亚洲经典一区 | 国产九一精品 | 亚洲日韩欧美一区二区在线 | av在线一区二区三区 | 免费色网址 | 欧美中文 | 国产精品久久久久久久久免费软件 | 国产国产精品久久久久 | 久久久99国产精品免费 | 四虎首页 | 在线国产小视频 | 欧美视频在线一区 | 狠狠干网站| 日韩一区二区三区在线观看视频 | 伦理午夜电影免费观看 | 91精品国产综合久久久久久蜜臀 | 亚州精品成人 | av片网| 久久一久久| 国产高清精品在线 | 日本一区不卡 | 国产福利视频网站 | 精品国产青草久久久久96 | 91视频一88av| 中文字幕在线视频一区二区三区 | 成人国产精品久久久 | 欧美h版 | 亚洲精品一区二区三区在线 | 人人看人人干 | 天堂影院av | 精品久久久久久久久亚洲 | 国产一区二区三区视频免费观看 | 日韩av成人 | av国产精品 | 1级毛片 | 国产成在线观看免费视频 | www.久久久久久久久久久 | 欧美久久久久久久久 | 亚洲精品自在在线观看 |