日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問(wèn) 生活随笔!

生活随笔

當(dāng)前位置: 首頁(yè) > 编程资源 > 编程问答 >内容正文

编程问答

【数据结构与算法】排序 冒泡、插入、选择 O(n^2)

發(fā)布時(shí)間:2023/12/10 编程问答 24 豆豆
生活随笔 收集整理的這篇文章主要介紹了 【数据结构与算法】排序 冒泡、插入、选择 O(n^2) 小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.

冒泡、插入、選擇 O(n2) 基于比較

快排、歸并 O(nlogn) 基于比較
計(jì)數(shù)、基數(shù)、桶 O(n) 不基于比較

一、如何分析一個(gè)排序算法?

  • 學(xué)習(xí)排序算法的思路?明確原理、掌握實(shí)現(xiàn)以及分析性能。
  • 如何分析排序算法性能?從執(zhí)行效率、內(nèi)存消耗以及穩(wěn)定性3個(gè)方面分析排序算法的性能。
  • 執(zhí)行效率:從以下3個(gè)方面來(lái)衡量
    1)最好情況、最壞情況、平均情況時(shí)間復(fù)雜度
    2)時(shí)間復(fù)雜度的系數(shù)、常數(shù)、低階:排序的數(shù)據(jù)量比較小時(shí)考慮
    3)比較次數(shù)和交換(或移動(dòng))次數(shù)
  • 內(nèi)存消耗:通過(guò)空間復(fù)雜度來(lái)衡量。針對(duì)排序算法的空間復(fù)雜度,引入原地排序的概念,原地排序算法就是指空間復(fù)雜度為O(1)的排序算法。
  • 穩(wěn)定性:如果待排序的序列中存在值等的元素,經(jīng)過(guò)排序之后,相等元素之間原有的先后順序不變,就說(shuō)明這個(gè)排序算法時(shí)穩(wěn)定的。
  • 二、冒泡排序

    1.排序原理

    1)冒泡排序只會(huì)操作相鄰的兩個(gè)數(shù)據(jù)。
    2)對(duì)相鄰兩個(gè)數(shù)據(jù)進(jìn)行比較,看是否滿足大小關(guān)系要求,若不滿足讓它倆互換。
    3)一次冒泡會(huì)讓至少一個(gè)元素移動(dòng)到它應(yīng)該在的位置,重復(fù)n次,就完成了n個(gè)數(shù)據(jù)的排序工作。
    4)優(yōu)化:若某次冒泡不存在數(shù)據(jù)交換,則說(shuō)明已經(jīng)達(dá)到完全有序,所以終止冒泡。

    2.代碼實(shí)現(xiàn)

    // 冒泡排序,a表示數(shù)組,n表示數(shù)組大小 public void bubbleSort(int[] a, int n) {if (n <= 1) return;for (int i = 0; i < n; ++i) {// 提前退出冒泡循環(huán)的標(biāo)志位boolean flag = false;for (int j = 0; j < n - i - 1; ++j) {if (a[j] > a[j+1]) { // 交換int tmp = a[j];a[j] = a[j+1];a[j+1] = tmp;flag = true; // 表示有數(shù)據(jù)交換 }}if (!flag) break; // 沒(méi)有數(shù)據(jù)交換,提前退出} }

    3.性能分析

    1)執(zhí)行效率:最小時(shí)間復(fù)雜度、最大時(shí)間復(fù)雜度、平均時(shí)間復(fù)雜度
    最小時(shí)間復(fù)雜度:數(shù)據(jù)完全有序時(shí),只需進(jìn)行一次冒泡操作即可,時(shí)間復(fù)雜度是O(n)。
    最大時(shí)間復(fù)雜度:數(shù)據(jù)倒序排序時(shí),需要n次冒泡操作,時(shí)間復(fù)雜度是O(n^2)。
    平均時(shí)間復(fù)雜度:通過(guò)有序度和逆序度來(lái)分析。
    對(duì)于包含n個(gè)數(shù)據(jù)的數(shù)組進(jìn)行冒泡排序,平均交換次數(shù)是多少呢?最壞的情況初始有序度為0,所以要進(jìn)行n*(n-1)/2交換。最好情況下,初始狀態(tài)有序度是n*(n-1)/2,就不需要進(jìn)行交互。我們可以取個(gè)中間值n*(n-1)/4,來(lái)表示初始有序度既不是很高也不是很低的平均情況。
    換句話說(shuō),平均情況下,需要n*(n-1)/4次交換操作,比較操作可定比交換操作多,而復(fù)雜度的上限是O(n2),所以平均情況時(shí)間復(fù)雜度就是O(n2)。
    2)空間復(fù)雜度:每次交換僅需1個(gè)臨時(shí)變量,故空間復(fù)雜度為O(1),是原地排序算法
    3)算法穩(wěn)定性:如果兩個(gè)值相等,就不會(huì)交換位置,故是穩(wěn)定排序算法

    三、 插入排序(Insertion Sort)

    1.算法原理

    首先,我們將數(shù)組中的數(shù)據(jù)分為2個(gè)區(qū)間,即已排序區(qū)間和未排序區(qū)間。初始已排序區(qū)間只有一個(gè)元素,就是數(shù)組的第一個(gè)元素。插入算法的核心思想就是取未排序區(qū)間中的元素,在已排序區(qū)間中找到合適的插入位置將其插入,并保證已排序區(qū)間中的元素一直有序。重復(fù)這個(gè)過(guò)程,直到未排序中元素為空,算法結(jié)束。

    2.代碼實(shí)現(xiàn)
    // 插入排序,a表示數(shù)組,n表示數(shù)組大小 public void insertionSort(int[] a, int n) {if (n <= 1) return;for (int i = 1; i < n; ++i) {int value = a[i];int j = i - 1;// 查找插入的位置for (; j >= 0; --j) {if (a[j] > value) {a[j+1] = a[j]; // 數(shù)據(jù)移動(dòng)} else {break;}}a[j+1] = value; // 插入數(shù)據(jù)} }

    3.性能分析

    1)時(shí)間復(fù)雜度:最好、最壞、平均情況
    如果要排序的數(shù)組已經(jīng)是有序的,我們并不需要搬移任何數(shù)據(jù)。只需要遍歷一遍數(shù)組即可,所以時(shí)間復(fù)雜度是O(n)。如果數(shù)組是倒序的,每次插入都相當(dāng)于在數(shù)組的第一個(gè)位置插入新的數(shù)據(jù),所以需要移動(dòng)大量的數(shù)據(jù),因此時(shí)間復(fù)雜度是O(n2)。而在一個(gè)數(shù)組中插入一個(gè)元素的平均時(shí)間復(fù)雜都是O(n),插入排序需要n次插入,所以平均時(shí)間復(fù)雜度是O(n2)。
    2)空間復(fù)雜度:從上面的代碼可以看出,插入排序算法的運(yùn)行并不需要額外的存儲(chǔ)空間,所以空間復(fù)雜度是O(1),是原地排序算法
    3)算法穩(wěn)定性:在插入排序中,對(duì)于值相同的元素,我們可以選擇將后面出現(xiàn)的元素,插入到前面出現(xiàn)的元素的后面,這樣就保持原有的順序不變,所以是穩(wěn)定的

    四、選擇排序(Selection Sort)

    1.算法原理

    選擇排序算法也分已排序區(qū)間和未排序區(qū)間。但是選擇排序每次會(huì)從未排序區(qū)間中找到最小的元素,并將其放置到已排序區(qū)間的末尾。

    2.代碼實(shí)現(xiàn)

    /*** 選擇排序* @param a 待排序數(shù)組* @param n 數(shù)組長(zhǎng)度*/ public static void selectSort(int[] a, int n) { if(n<=0) return;for(int i=0;i<n;i++){int min=i;for(int j=i;j<n;j++){if(a[j] < a[min]) min=j;}if(min != i){int temp=a[i];a[i]=a[min];a[min]=temp;}} }

    3.性能分析

    1)時(shí)間復(fù)雜度:最好、最壞、平均情況
    選擇排序的最好、最壞、平均情況時(shí)間復(fù)雜度都是O(n2)。為什么?因?yàn)闊o(wú)論是否有序,每個(gè)循環(huán)都會(huì)完整執(zhí)行,沒(méi)得商量。
    2)空間復(fù)雜度:
    選擇排序算法空間復(fù)雜度是O(1),是一種原地排序算法
    3)算法穩(wěn)定性:
    選擇排序算法不是一種穩(wěn)定排序算法,比如[5,8,5,2,9]這個(gè)數(shù)組,使用選擇排序算法第一次找到的最小元素就是2,與第一個(gè)位置的元素5交換位置,那第一個(gè)5和中間的5的順序就變量,所以就不穩(wěn)定了。正因如此,相對(duì)于冒泡排序和插入排序,選擇排序就稍微遜色了。

    五、冒泡排序和插入排序的時(shí)間復(fù)雜度都是 O(n^2),都是原地排序算法,為什么插入排序要比冒泡排序更受歡迎呢?

    冒泡排序移動(dòng)數(shù)據(jù)有3條賦值語(yǔ)句,而選擇排序的交換位置的只有1條賦值語(yǔ)句,因此在有序度相同的情況下,冒泡排序時(shí)間復(fù)雜度是選擇排序的3倍,所以,選擇排序性能更好。

    冒泡排序中數(shù)據(jù)的交換操作: if (a[j] > a[j+1]) { // 交換int tmp = a[j];a[j] = a[j+1];a[j+1] = tmp;flag = true; }插入排序中數(shù)據(jù)的移動(dòng)操作: if (a[j] > value) {a[j+1] = a[j]; // 數(shù)據(jù)移動(dòng) } else {break; }

    筆記整理來(lái)源: 王爭(zhēng) 數(shù)據(jù)結(jié)構(gòu)與算法之美

    創(chuàng)作挑戰(zhàn)賽新人創(chuàng)作獎(jiǎng)勵(lì)來(lái)咯,堅(jiān)持創(chuàng)作打卡瓜分現(xiàn)金大獎(jiǎng)

    總結(jié)

    以上是生活随笔為你收集整理的【数据结构与算法】排序 冒泡、插入、选择 O(n^2)的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。

    如果覺(jué)得生活随笔網(wǎng)站內(nèi)容還不錯(cuò),歡迎將生活随笔推薦給好友。