1、归并排序:时间最差o(nlogn) 空间O(n),稳定排序,算法表现也很稳定
void merge(int list[], int s, int mid, int e)
{
int n1 = mid-s;
int n2 = e-mid;
int *list1= new int[n1+1];
int *list2= new int[n2+1]; // 将前半部分和后半部分分别赋给数组list1和list2
int i=0;
for(i=0;i<n1;i++)
list1[i] = list[i+s];
list1[n1] = INT_MAX;
for(i=0;i<n2;i++)
list2[i] = list[i+mid];
list2[n2] = INT_MAX; // 加入哨兵
int i1=0, i2=0;
i=0;
while(i<n1+n2) // 注意list从s开始到e,而list1和list2是从0开始,索引不要弄错!
list[s+i++] = list1[i1]<list2[i2]?list1[i1++]:list2[i2++];
delete[] list1,list2;
}
void mergesort(int *list, int s, int e)
{
if (s+1>=e) // 只有一个数则不merge
return;
int mid = (e-s)/2+s;
//cout<<"s mid e "<<s<<' '<<mid<<' '<<e<<endl;
mergesort(list, s, mid);
mergesort(list, mid, e);
merge(list, s, mid, e);
}
2、快排:时间期望o(nlogn) 空间O(1)(性能差异大)不稳定排序
// 快排的partition函数
int partition(int *list, int s, int e)
{
int flag = list[e-1];
int i=s,j=s-1,tmp;
for (;i<e;i++)
{
if (list[i]<=flag)
{
j++;
tmp = list[i];
list[i] = list[j];
list[j] = tmp;
}
}
return j;
}
// 快排 10**5 需要0.262秒
void quicksort(int *list, int s, int e)
{
if (s+1>=e)
return;
int deli = partition(list, s, e);
quicksort(list, s, deli);
quicksort(list, deli+1, e);
}
void insertsort(int *list, int n)
{
int j,tmp;
for(int i=1;i<n;i++)
{
j = i-1;
tmp = list[i];
while(j>=0 && list[j]>tmp) // 前面的大,则向后移一位
{
list[j+1] = list[j];
j--;
}
list[j+1] = tmp;
}
}
n=10^5 时耗时 7.023 秒
class Heap
{
public:
int length;
int heapsize;
int *list;
Heap(int *li, int n)
{
length = n;
heapsize = n;
list = new int[n];
for(int i=0;i<n;i++)
list[i] = li[i];
buildheap();
}
~Heap(){delete[] list;}
// 左右节点,父节点,交换
int left(int i){return i*2+1;}
int right(int i){return i*2+2;}
int pre(int i){return (i-1)/2;}
void swap(int &x, int &y){int tp=x;x=y;y=tp;}
// 保持堆的性质
void heapify(int i)
{
int imax = i;
if (left(i)<heapsize && list[left(i)]>list[imax])
imax = left(i);
if (right(i)<heapsize && list[right(i)]>list[imax])
imax = right(i);
if (imax!=i)
{
swap(list[imax], list[i]);
heapify(imax);
}
}
// 建堆
void buildheap()
{
for (int i=heapsize/3;i>=0;i--) // 从有子节点的节点往上heapify
heapify(i);
}
// 堆排序
void heap_sort()
{
for (int i=length-1;i>0;i--)
{
//cout<<"heapsize: "<<heapsize<<endl;
swap(list[0], list[i]);
heapsize--;
heapify(0);
}
}
// 返回最大值
int getmax(){return list[0];}
// 抽取最大值
int exctratmax()
{
swap(list[0], list[heapsize-1]);
heapsize--;
heapify(0);
return list[heapsize];
}
};
n=10^5 时耗时 0.331 秒,建堆O(n),heapify O(logn);排序时将顶点元素换至队尾,再对顶点元素进行heapify,因此复杂度为nlogn