常見排序演算法整理2(C++實現)
1. 歸併排序
- 時間複雜度:O(nlogn)
- 空間複雜度:O(n)
演算法的基本思想:將每兩個相鄰元素進行歸併,得到新的歸併陣列,每兩個一組再次進行歸併排序,直到所有元素均已排序。
C++實現:
void mergehelp(int* A,int left,int mid,int right)
{
int* B=new int[right-left+1];
int index=0;
int i=left;
int j=mid+1;
while(i<=mid&&j<=right)
{
B[index++]=A[i]<=A[j]?A[i++]:A[j++];
}
while(i<=mid)
{
B[index++]=A[i++];
}
while(j<=right)
{
B[index++]=A[j++];
}
for(int i=0;i<index;i++)
{
A[left++]=B[i];
}
}
void merge(int* A,int left,int right)
{
if(left>=right)
return;
int mid=(left+right)/2;
merge(A,left,mid);
merge(A,mid+1,right);
mergehelp(A,left,mid,right);
}
int* mergeSort(int* A, int n) {
int left=0;
int right=n-1;
merge(A,0,n-1);
return A;
}
2. 快速排序
- 時間複雜度:O(nlogn)
- 空間複雜度:O(logn)
演算法的基本思想:
通過partition函式尋找位置點,利用遞迴地思想,不斷對兩部分陣列進行劃分,直到陣列的個數為1。partition函式的思想,可以通過填坑法來尋找劃分點pivot,將大於等於pivot值的元素放在陣列右側,將小於等於pivot值的元素放在陣列左側,返回劃分點pivot的位置。
C++實現:
int partition(int* A,int left,int right)
{
int pivot=A[left];
while(left<right)
{
while(left<right&&A[right]>=pivot)
{
right--;
}
swap(A[left],A[right]);
while(left<right&&A[left]<=pivot)
{
left++;
}
swap(A[left],A[right]);
}
return left;
}
void quickSortHelp(int* A,int left,int right)
{
if(left<right)
{
int pivot=partition(A,left,right);
quickSortHelp(A,left,pivot-1);
quickSortHelp(A,pivot+1,right);
}
}
int* quickSort(int* A, int n) {
int left=0;
int right=n-1;
quickSortHelp(A,left,right);
return A;
}
3. 堆排序
- 時間複雜度:O(nlogn)
- 空間複雜度:O(1)
- 演算法的基本思想:構造一個最大堆,堆頂的元素為最大值,將堆頂元素與陣列的最後一個元素交換,則最後一個元素已排序好。不斷地將堆頂元素與最後一個元素交換,直到陣列的個數為一。每次交換後,都需要利用heapify函式對堆進行一次調整。構造最大堆的過程也是利用heapify函式對陣列值不斷進行調整。
- C++實現:
{
int cur=left;
int child=2*cur+1;
while(child<right)
{
if(child+1<right&&A[child+1]>A[child])
{
child++;
}
if(A[child]>A[cur])
{
swap(A[cur],A[child]);
cur=child;
child=2*cur+1;
}
else
{
break;
}
}
}
int* heapSort(int* A, int n) {
for(int i=n/2-1;i>=0;i--)
{
heapify(A,i,n-1);
}
for(int i=n-1;i>0;i--)
{
swap(A[i],A[0]);
heapify(A,0,i);
}
return A;
}
4. 希爾排序
- 時間複雜度:O(nlogn)
- 空間複雜度:O(1)
- 演算法的基本思想:希爾排序是插入排序的衍生版本。設定一個增量d,將陣列元素分到d個增量中,在每一個增量中採用插入排序。之後縮小增量d的值,再次將元素分到d個增量中,進行插入排序。直到增量d為1,完成排序。
int d=n/2;
while(d>=1)
{
for(int i=d;i<n;i++)
{
int get=A[i];
int j=i-d;
while(j>=0&&A[j]>=get)
{
A[j+d]=A[j];
j=j-d;
}
A[j+d]=get;
}
d=d/2;
}
return A;
}