快速排序與歸併排序

2021-10-02 09:29:15 字數 2323 閱讀 7702

難度偏低,適合入門

思想:(複雜度nlog n)

[…………]

[……]a[……]

[…]a[…]a[…]b[…]

例如:2 3 5 1 7 6 4 8

[2 3 1 4] 5 [7 6 8]

[2] 3 [1 4] 5 [7] 6 [8]

......(log n層)

最後只剩乙個元素

核心:如何把乙個陣列劈開(**如下)

void

quirt

(int i,

int j)

if(l=a[r]

;while

(l<=t)

if(l=a[l];}

a[l]

=t;quirt

(i,l-1)

;quirt

(l+1

,j);

//穩定性:不穩定

//快速排序演算法遇到有序陣列會退化到o(n^2)

}

t=4;

4 2 5 3 1 6 7

i j

先找到第乙個比t小的數,賦值為a[l],再找到第乙個比t大的數放到a[r]處,最後把t放入a[l]=t;

最後得1 2 4 3 5 6 7

i j

a : 1 3 4 5

b : 2 3 3 7

c[k++]=a[i++]; if ( a [i] <= b [i] )

c[k++]=b[j++]; if ( a [i] > b [i] )

如果還有剩餘,用while直接讀入即可

const

int m=

100050

;const

int n=

200050

;int a[m]

,b[m]

,c[n]

;int n,m;

void

merge

(int a,

int b,

int c)

while

(ielse

if(a[i]

>b[j])}

while

(iwhile

(j}

優化:(分治)

sort

(int l,

int r)

int mid=

(l+r)/2

;sort

(l,mid)

;sort

(mid+

1,r)

;int i=l,j=mid+

1,k=l;

while

(i<=mid&&j<=r)

else

}while

(i<=mid)

while

(j<=r)

//tmp為有序陣列

for(

int i=l;i<=r;i++

)//每一層的複雜度都是o(n),共是o(nlog n)的複雜度

}

逆序對題目

給定乙個長度為n的排列a,逆序的定義:(i,j)為逆序對,當ia[j] ,求排列a的逆序對數量。

輸入第一行乙個整數n,表示排列的長度,第二行n個元素,表示a排列

輸出輸出逆序對數目

int a[

100010

],b[

100010];

int n;

long

long cnt;

void

solve_sort

(int i,

int j)

int mid=

(l+r)/2

;int t=l,c=mid+1;

solve_sort

(i,mid)

;solve_sort

(mid+

1,j)

;while

(l<=mid&&r>=c)

else

}while

(l<=mid)

while

(c<=r)

for(

int k=i;k<=j;k++)}

intmain()

solve_sort(0

,n-1);

printf

("%lld"

,cnt)

;return0;

}

歸併排序與快速排序

1.演算法簡介 歸併排序和快速排序都是採用遞迴的結構實現的,不同的是歸併排序在遞迴過程中有合併子串行的過程,而快速排序中沒有,但是快速排序中有較為複雜的劃分過程。二者的平均時間複雜度均為o nlgn 其中快速排序的係數較小 歸併排序最壞情況複雜度為o nlgn 快排在最壞情況下時間複雜度為o n 2...

快速排序與歸併排序

簡單總結一下快速排序和歸併排序的用法,這兩種方法十分省時,在題目中常用。快速排序 基本思想通過一趟排序將代拍記錄分成兩部分,一部分記錄關鍵字比另一部分小,再對這兩部分記錄繼續排序,達到整個序列有序。具體做法是附設兩個指標i和j,初值分別為l,r,任選乙個記錄做樞紐取mid,首先從j位置向前搜找到第乙...

歸併排序與快速排序

1.分治思想顧名思義,就是分而治之的意思,將大問題換分為無數個小問題,小的問題解決了,大的問題自然也就解決了。分之演算法一般都是用遞迴來實現的。分治是一種解決問題的處理思想,遞迴是是一種程式設計技巧。2.歸併排序歸併排序的核心思想 就是講乙個陣列分為前後兩部分分別進行排序,然後將有序的兩個陣列再合併...