排序演算法及其效率分析(一)內排序

2021-07-02 04:11:22 字數 2977 閱讀 9706

只要是接觸程式設計,接觸演算法,排序是必修的一門基礎課,它的應用之大不言而喻,下面就幾種常用排序進行實現並進行時間複雜度的分析:

1:選擇排序法

舉個例子:對於2 9 5 4 8 1 6

step1:在列表中先選擇最大元9並與最後乙個數字6交換 2 6 5 4 8 1 9;

step2:在剩餘列表選擇最大元8並與最後乙個數字1交換 2 6 5 4 1 8 9;

step3:在剩下列表選擇最大元6並與最後乙個數字1交換 2 1 5 4 6 8 9;

step4:在剩下列表選擇最大元5並與最後乙個數字4交換 2 1 4 5 6 8 9;

step5:剩下列表最大元4已經在合適位置不用交換;

step6:在剩下列表選擇最大元2並與最後乙個數字1交換 1 2 4 5 6 8 9;

最後只剩乙個數字,無需再排序,排序完成。

演算法時間複雜度分析:第一步迭代需要n-1次比較操作;第二步需要n-2個比較。。。c表示其他常見操作(賦值,每次迭代的比較)

t(n)=n-1+n-2+...+1+c*(n-1)=n^2/2-n/2+c*(n-1)=o(n^2)

**:

void sort_sele(int a,int size)

a[j+1]=re;}

}

3:氣泡排序演算法

例子:2 9 5 4 8 1 6

step1:將2 9交換,因為已經是公升序不用再動;將9 5交換成5 9;將9 4 交換成4 9;將9 8交換成8 9;將9 1交換成1 9;將9 6交換成6 9;----最大元素沉底2 5 4 8 1 6 9;

step2: 類似的將8沉底得到2 4 5 1 6 8 9;

step3:類似的將6沉底得到2 4 5 1 6 8 9;

step4:類似的將5沉底得到2 4 1 5 6 8 9;

step5:類似的將4沉底得到2 1 4 5 6 8 9;

step6:類似的將2沉底得到1 2 4 5 6 8 9;

最後完成

演算法分析:

在最好情況時第一步就發現已經有序,則無需再操作,比較此時n-1,o(n);

最壞情況:總共n-1次掃瞄;第k次掃瞄需要比較n-k次比較

t(n)=1+2+...(n-1)+c*(n-1)=o(n^2);

**:

void sort_mao(int a,int size)

}}

4:歸併排序演算法:

它是一種遞迴演算法,將陣列劃分兩半,對每一半不斷遞迴知道得到乙個元素的陣列,然後對最終子陣列進行歸併排序

演算法效能分析:t(n)=t(n/2)+t(n/2)+合併時間

第乙個t(n/2)是陣列前一半所需,第二個t(n/2)是陣列後一半所需,合併時間包括n-1次比較和n次n次移動

t(n)=t(n/2)+t(n/2)+2*n-1=2*t(n/2)+2*n-1=2*(2*t(n/4)+2*n/2-1)+2*n-1=...=2nlogn+!=o(nlogn);

**:

歸併演算法之分半部分

void copy(int source,int sindex,int dest,int dindex,int len)//將a,b裡面較小的放入temp,直到乙個放完

while(i11)

}

5:快速排序演算法:

首先在陣列中選擇乙個元素做樞軸,將陣列分為兩部分,第一部分都小於樞軸,第二部分都大於,隨後對子陣列遞迴使用快速排序

例如2 9 5 4 8 1 6

step1:選擇第乙個元素2為樞軸,分成兩部分:1   2   5 4 8 9 6

step2:對於5 4 8 9 6 選擇第乙個元素5為樞軸,分成4 5  8 9 6

step3:對於8 9 6以排好序

演算法效能:快速演算法主要分為劃分函式部分,在最壞情況下,需要花費n次比較,n次移動故劃分時間複雜度o(n)

t(n)=t(n/2)*2+n(劃分時間)=o(n*logn)

**:

//快速排序之劃分

int part(int a,int first,int last)

} //返回此次樞軸的座標

while(high>first&&pivote<=a[high])high--;

if(pivote>a[high])

else return first;}

//快速排序

void quicksort(int a,int first,int last)

}void quicksort(int a,int size)

5:堆排序演算法

二叉樹滿足:每個節點都大於等於其任何子節點:首先使用heap類建立乙個物件,使用add函式將元素入堆,然後使用remove函式刪除返回,從而完成排序

演算法效能分析:h表示乙個n個元素的堆的高度,由於堆是完全二叉樹,所以第k層有2^(k-1)個節點,第h層至少乙個節點,至多2^(h-1)

1+2.。。+2^(h-2)可以得到  h-1t(n)=o(n*logn)+o(n*logn)=o(n*logn)

**:

#include"heap.h"

void sort_sort(int a,int size){

heapheap;

for(int i=0;i

總結:一、歸併排序和快速排序都使用了分而治之思想,歸併重在列表合併操作,發生在子列表都排序之後;而快速排序重在列表劃分,發生在子列表都排序之前。歸併最壞情況好於快速,但是平均情況都是o(n*logn),但是歸併還需要乙個臨時陣列故空間複雜度高一些。堆的時間複雜度也是o(nlogn),不用額外陣列。冒泡,插入,選擇的平均複雜度o(n^2)

二、選擇排序、快速排序、希爾排序、堆排序不是穩定的排序演算法,而 冒泡 排序、插入排序、歸併排序和基數排序是穩定的排序演算法。

排序演算法效率分析

目錄 排序方法 時間複雜度 平均 時間複雜度 最壞 時間複雜度 最好 空間複雜度 穩定性氣泡排序 o n2 o n2 o n o 1 穩定選擇排序 o n2 o n2 o n2 o 1 不穩定插入排序 o n2 o n2 o n o 1 穩定希爾排序 o n1.3 o n2 o n o 1 不穩定快...

幾種排序演算法及其效率對比

public class bubblesort sort arr system.out.println arrays.tostring arr long start system.currenttimemillis sort arr long end system.currenttimemillis...

內排序演算法

每次需要排序的時候總是會忘記基本的排序演算法,為了防止自己再次忘記,寫個部落格加深自己的印象 簡單選擇排序大概就是最簡單我們最容易想到的一種排序方法,一共進行n 1次選擇,在第i次選擇中選擇第i小的數放在相應的位置。我們可以想象一種場景,有一些賬單需要我們按照時間進行排序,我媽每次選擇最早的一張拿在...