八大排序演算法

2021-10-04 00:17:45 字數 3629 閱讀 7312

1.直接插入排序:

平均時間複雜度o(n2),最好o(n),最差o(n2),空間o(1)

思路:從前往後擴大範圍,只移動乙個元素

void

swapint

(int

*a,int

*b)void

insertsort

(int data,

int length,

int start,

int end)

2.shell排序:

平均時間複雜度o(n^2),最好o(n),最差o(n^2),空間o(1)

void

shellsort

(int data,

int length,

int start,

int end)

}

shell排序是基於插入排序來進行改進的:

插入排序對於幾乎已經排好的資料進行操作時,效率高,可以基本達到線性排序(就是o(n)時間複雜度內完成的排序)的效果;

但一般的插入排序一次只能將資料移動一位,效率很低

因此先從大的範圍內進行插入排序,然後降低插入排序的移動次數

經過測試,排序12個整數,一般的直接插入排序需要交換47次資料,而shell排序只需要交換13次

但是shell排序不穩定,直接插入排序穩定

3.直接選擇排序:

平均、最好、最壞都是o(n^2)

思路:從前往後擴大範圍,不斷找最小的放在最前面。

void

selectsort

(int data,

int length,

int start,

int end)

}

4.堆排序:

最好、最壞、平均都是o(nlogn)

堆:本質是乙個陣列表現的完全二叉樹(從左到有節點應該是滿的,但不一定是滿二叉樹,最後一層不一定滿)。

完全二叉樹:當二叉樹的深度為h時,它的h層節點必須都是連續靠左並不可隔開的(滿二叉樹也符合),並且1~h-1層的結點數都達到最大個數(即1~h-1層為乙個滿二叉樹)。

滿二叉樹:深度為k(根節點也算是一層深度),並且一定有2^k-1個結點。

分為最大堆和最小堆。任意葉節點都大於/小於/等於父節點。但是對於兩個兒子節點沒有要求。

堆排序的過程:

構造」最大堆「/」最小堆「

堆頂節點資料為最大值/最小值

將堆頂和末尾資料進行交換,然後將剩下的n-1個元素重新構造成堆

繼續獲取頂部節點

迴圈往復,直到沒有節點

//從上往下遞迴構造堆,length是總的陣列長度,index是第乙個非葉子節點

//但是遞迴過程只是往已交換的那個方向子樹去遞迴,因此如果整棵樹是凌亂的話,需要像heapsort裡面那樣迴圈進行呼叫,重新構造

void

makeheap

(int data,

int length,

int index)

}void

heapsort

(int data,

int length)

}

可見:想要獲得遞減排序,就要用最大堆,想要遞增排序,就用最小堆。

5. 氣泡排序:

o(n^2)

void bubblesort(int data, int length, int start, int end)

intrandominrange

(int start,

int end)

//範圍內隨機選乙個就好

intpartition

(int data,

int length,

int start,

int end)

}++bound;

swapint

(&data[bound]

,&data[end]);

//將基準值放回兩部分數的中間

return bound;

}void

quicksort

(int data,

int length,

int start,

int end)

7. 歸併排序:

經典的分治策略(divide and conquer)

時間複雜度:o(nlogn),空間複雜度o(n)

void

merge

(int data,

int start,

int mid,

int end,

int temp)

//需要乙個臨時的陣列來用於存放merge的臨時結果

//在排序前,先建好乙個長度等於原陣列長度的臨時陣列,避免遞迴中頻繁開闢空間

void

mergesort

(int data,

int length,

int start,

int end,

int temp)

intmain

(int argc,

char

* ar**)

; size_t length =

sizeof

(arr)

/sizeof

(int);

int*temp =

newint

[length];

mergesort

(arr, length,

0, length-

1, temp)

;for

(int i =

0; i < length;

++i)

cout << arr[i]

<<

" ";

delete

temp;

//釋放動態陣列的空間

system

("pause");

return0;

}

8. 基數排序:

時間複雜度o(d(r+n)),d是數字的位數,n是數字的個數,r是基數10

通過序列中各個元素的值,對排序的n個元素進行若干趟的「分配」與「收集」來實現排序。

//獲取序列中,最大的位數,比如最大123,那麼就返回3

//這決定了基數排序中分配和收集迴圈的次數

intmaxbit

(int data,

int length)

return maxb;

}void

radixsort

(int data,

int length)

for(

int j =

0; j < length;

++j)

data[j]

= buckets[j]

; radix *=10

;}delete

buckets;

}

八大排序演算法

1.直接插入排序 原理 將陣列分為無序區和有序區兩個區,然後不斷將無序區的第乙個元素按大小順序插入到有序區中去,最終將所有無序區元素都移動到有序區完成排序。要點 設立哨兵,作為臨時儲存和判斷陣列邊界之用。實現 void insertsort node l,int length void shell ...

八大排序演算法

一 概述 八大排序演算法包括 1 插入排序之直接插入排序 straight insertion sort 2 插入排序之希爾排序 shells sort 3 選擇排序之簡單選擇排序 selection sort 4 選擇排序之堆排序 heap sort 5 交換排序之氣泡排序 bubble sort...

八大排序演算法

排序的定義 輸入 n個數 a1,a2,a3,an 輸出 n個數的排列 a1 a2 a3 an 使得a1 a2 a3 an in place sort 不占用額外記憶體或占用常數的記憶體 插入排序 選擇排序 氣泡排序 堆排序 快速排序。out place sort 歸併排序 計數排序 基數排序 桶排序...