難度偏低,適合入門
思想:(複雜度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.歸併排序歸併排序的核心思想 就是講乙個陣列分為前後兩部分分別進行排序,然後將有序的兩個陣列再合併...