乡下人产国偷v产偷v自拍,国产午夜片在线观看,婷婷成人亚洲综合国产麻豆,久久综合给合久久狠狠狠9

  • <output id="e9wm2"></output>
    <s id="e9wm2"><nobr id="e9wm2"><ins id="e9wm2"></ins></nobr></s>

    • 分享

      圖解:常用排序算法(冒泡、選擇、插入、希爾、快速、歸并、堆)

       waston 2019-02-11

      1 冒泡排序

      平均時間復(fù)雜度:O(n^2)

      穩(wěn)定性:穩(wěn)定(排序前后,相同元素的相對位置保持不變)


      1. private static void sort(int[] data) {
      2. for (int i = 0; i < data.length - 1; i++) {
      3. boolean complete = true;
      4. for (int j = 0; j < data.length - 1 - i; j++) {
      5. if (data[j] > data[j + 1]) {
      6. int temp = data[j];
      7. data[j] = data[j + 1];
      8. data[j + 1] = temp;
      9. complete = false;
      10. }
      11. }
      12. if (complete) {
      13. break;
      14. }
      15. }
      16. }



      2 選擇排序


      平均時間復(fù)雜度:O(n^2)

      穩(wěn)定性:不穩(wěn)定(排序后,相同元素的相對位置可能發(fā)生變化)


      1. private static void sort(int[] data) {
      2. for (int i = data.length - 1; i > 0; i--) {
      3. int maxIndex = i;
      4. for (int j = 0; j < i; j++) {
      5. if (data[j] > data[maxIndex]) {
      6. maxIndex = j;
      7. }
      8. }
      9. int temp = data[i];
      10. data[i] = data[maxIndex];
      11. data[maxIndex] = temp;
      12. }
      13. }



      3 插入排序


      平均時間復(fù)雜度:O(n^2)

      穩(wěn)定性:穩(wěn)定(排序前后,相同元素的相對位置保持不變)

      適用場景:部分元素已有序


      1. private static void sort(int[] data) {
      2. for (int i = 1; i < data.length; i++) {
      3. for (int j = i; j > 0; j--) {
      4. if (data[j] < data[j - 1]) {
      5. int temp = data[j];
      6. data[j] = data[j - 1];
      7. data[j - 1] = temp;
      8. } else {
      9. break;
      10. }
      11. }
      12. }
      13. }




      4 希爾排序


      平均時間復(fù)雜度:O(n^1.25)

      穩(wěn)定性:不穩(wěn)定(排序后,相同元素的相對位置可能發(fā)生變化)

      適用場景:大規(guī)模亂序

      相關(guān)說明:希爾排序是基于插入排序進(jìn)行改進(jìn)而來的算法。插入排序只交換相鄰的元素,在大規(guī)模亂序情況下,極有可能發(fā)生某個元素從某一端逐位交換至另一端,嚴(yán)重影響效率。希爾排序的思路是:先進(jìn)行遠(yuǎn)距離跨越交換,從而使得元素盡快靠近最終位置,達(dá)到部分有序的目的,然后,再進(jìn)行插入排序(當(dāng)H=1時)。


      1. private static void sort(int[] data) {
      2. int N = data.length;
      3. int h = 1;
      4. while (h < N / 3) {
      5. h = 3 * h + 1; // 1, 4, 13, 40, 121, 364, 1093, ...
      6. }
      7. while (h >= 1) {
      8. for (int i = 0; i < h; i++) {
      9. for (int j = i + h; j < N; j = j + h) {
      10. for (int k = j; k > i; k = k - h) {
      11. if (data[k] < data[k - h]) {
      12. int temp = data[k];
      13. data[k] = data[k - h];
      14. data[k - h] = temp;
      15. } else {
      16. break;
      17. }
      18. }
      19. }
      20. }
      21. h = h / 3;
      22. }
      23. }



      5 快速排序


      平均時間復(fù)雜度:O(nlogn)

      穩(wěn)定性:不穩(wěn)定(排序后,相同元素的相對位置可能發(fā)生變化)

      相關(guān)說明:首先,選擇一個元素,將其余元素分成三部分,一部分小于該元素,一部分大于該元素,一部分等于該元素。然后,對于前兩部分元素,再重復(fù)進(jìn)行上述操作,直至每個部分都已有序。


      1. private static void sort(int[] data, int leftStart, int rightEnd) {
      2. if (leftStart >= rightEnd)
      3. return;
      4. int leftIndex = leftStart;
      5. int rightIndex = rightEnd;
      6. int index = leftIndex + 1;
      7. int divisionValue = data[leftStart];
      8. while (index <= rightIndex) {
      9. if (data[index] < divisionValue) {
      10. int temp = data[index];
      11. data[index] = data[leftIndex];
      12. data[leftIndex] = temp;
      13. leftIndex++;
      14. index++;
      15. } else if (data[index] > divisionValue) {
      16. int temp = data[index];
      17. data[index] = data[rightIndex];
      18. data[rightIndex] = temp;
      19. rightIndex--;
      20. } else {
      21. index++;
      22. }
      23. }
      24. sort(data, leftStart, leftIndex - 1);
      25. sort(data, rightIndex + 1, rightEnd);
      26. }

      以首元素7分割數(shù)組


      對于左半部分,重復(fù)操作:以首元素分割數(shù)組



      6 歸并排序


      平均時間復(fù)雜度:O(nlogn)

      穩(wěn)定性:穩(wěn)定(排序前后,相同元素的相對位置保持不變)

      適用場景:合并多個已有序的子數(shù)組

      相關(guān)說明:分治思想(分而治之)的典型案例。有自頂向下和自底向上兩種方式。


      1. // 自底向上方式
      2. private static void sort(int[] data) {
      3. int N = data.length;
      4. for (int size = 1; size < N; size = size + size) {
      5. for (int leftStart = 0; leftStart + size < N; leftStart = leftStart + size + size) {
      6. merge(data, leftStart, leftStart + size - 1, Math.min(leftStart + size + size - 1, N - 1));
      7. }
      8. }
      9. }
      10. private static void merge(int[] data, int leftStart, int leftEnd, int rightEnd) {
      11. int leftIndex = leftStart;
      12. int rightIndex = leftEnd + 1; // rightStart
      13. int[] temp = new int[data.length];
      14. for (int k = leftStart; k <= rightEnd; k++) {
      15. temp[k] = data[k];
      16. }
      17. for (int k = leftStart; k <= rightEnd; k++) {
      18. if (leftIndex > leftEnd) {
      19. data[k] = temp[rightIndex++];
      20. } else if (rightIndex > rightEnd) {
      21. data[k] = temp[leftIndex++];
      22. } else if (temp[leftIndex] < temp[rightIndex]) {
      23. data[k] = temp[leftIndex++];
      24. } else {
      25. data[k] = temp[rightIndex++];
      26. }
      27. }
      28. }

      歸并兩個已有序的子數(shù)組


      自底向上方式排序



      7 堆排序


      平均時間復(fù)雜度:O(nlogn)

      穩(wěn)定性:不穩(wěn)定(排序后,相同元素的相對位置可能發(fā)生變化)


      堆有序:在一顆二叉樹中,每個結(jié)點(diǎn)都大于等于它的兩個子節(jié)點(diǎn)。

      二叉堆:堆有序的完全二叉樹。


      二叉堆數(shù)組:將完全二叉樹的結(jié)點(diǎn),按照層級順序,將每一層的結(jié)點(diǎn),從左至右放入數(shù)組中,且下標(biāo)從1開始,即根節(jié)點(diǎn)的下標(biāo)為1位置。


      堆的有序化


      1. private static void swim(int[] data, int index) {
      2. while (index > 1) {
      3. if (data[index / 2] < data[index]) {
      4. int temp = data[index];
      5. data[index] = data[index / 2];
      6. data[index / 2] = temp;
      7. index = index / 2;
      8. } else {
      9. break;
      10. }
      11. }
      12. }

      上浮方式



      1. private static void sink(int[] data, int index) {
      2. while (2 * index <= data.length - 1) {
      3. int childIndex = 2 * index;
      4. if (childIndex + 1 <= data.length - 1) {
      5. if (data[childIndex] < data[childIndex + 1]) {
      6. childIndex++;
      7. }
      8. }
      9. if (data[index] < data[childIndex]) {
      10. int temp = data[index];
      11. data[index] = data[childIndex];
      12. data[childIndex] = temp;
      13. index = childIndex;
      14. } else {
      15. break;
      16. }
      17. }
      18. }

      下沉方式


      堆排序


      1. private static void sort(int[] data) {
      2. for (int index = (data.length - 1) / 2; index >= 1; index--) {
      3. sink(data, index, data.length - 1);
      4. }
      5. for (int index = data.length - 1; index > 1; index--) {
      6. int temp = data[index];
      7. data[index] = data[1];
      8. data[1] = temp;
      9. sink(data, 1, index - 1);
      10. }
      11. }
      12. /**
      13. *
      14. * @param data
      15. * @param index
      16. * @param lastIndex 用于排除已經(jīng)完成排序的位置
      17. */
      18. private static void sink(int[] data, int index, int lastIndex) {
      19. while (2 * index <= lastIndex) {
      20. int childIndex = 2 * index;
      21. if (childIndex + 1 <= lastIndex) {
      22. if (data[childIndex] < data[childIndex + 1]) {
      23. childIndex++;
      24. }
      25. }
      26. if (data[index] < data[childIndex]) {
      27. int temp = data[index];
      28. data[index] = data[childIndex];
      29. data[childIndex] = temp;
      30. index = childIndex;
      31. } else {
      32. break;
      33. }
      34. }
      35. }

      堆有序化


      排序



        本站是提供個人知識管理的網(wǎng)絡(luò)存儲空間,所有內(nèi)容均由用戶發(fā)布,不代表本站觀點(diǎn)。請注意甄別內(nèi)容中的聯(lián)系方式、誘導(dǎo)購買等信息,謹(jǐn)防詐騙。如發(fā)現(xiàn)有害或侵權(quán)內(nèi)容,請點(diǎn)擊一鍵舉報。
        轉(zhuǎn)藏 分享 獻(xiàn)花(0

        0條評論

        發(fā)表

        請遵守用戶 評論公約

        類似文章 更多