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;
}