来源:脑客爱刷题
快速排序:
本算法主要改进了快排的partition算法,使得每次partition后,等于target的数在未排序部分的“中间”连续出现,target左边部分比它小,右边部分比它大。
void partition(vector<int> &num, int begin, int end)
{
if (begin >= end)
return;
int smaller = begin - 1, bigger = end + 1, cur = begin + 1, target = num[begin];
while (cur != bigger)
{
if (num[cur] == target)
{
cur++;
}
else if (num[cur] < target)
{
swap(num[cur], num[smaller + 1]);
smaller++;
cur++;
}
else
{
swap(num[cur], num[bigger - 1]);
bigger--;
}
}
partition(num, begin, smaller);
partition(num, bigger, end);
}
void quicksort(vector<int> &num)
{
if (num.size() <= 1)
return;
partition(num, 0, num.size() - 1);
}
堆排序:
//数组[0,index-1]的范围内都是已经建成的最大堆,现在要把num[index]加入堆中
void heapInsert(vector<int> &num, int index)
{
while (index != 0)
{
int parent = (index - 1) / 2;
if (num[parent] < num[index])
swap(num[parent], num[index]);
else
break;
index = parent;
}
}
//num[0]不在堆的正确位置,把它往下“沉”,直到正确位置为止,堆的范围是[0,size-1]
void heapDown(vector<int> &num, int size)
{
int index = 0, largest = index, left = index * 2 + 1, right = index * 2 + 2;
while (left < size)
{
if (num[left] > num[largest])
largest = left;
if (right<size && num[right] > num[largest])
largest = right;
if (largest != index)
{
swap(num[largest], num[index]);
index = largest;
left = index * 2 + 1;
right = index * 2 + 2;
}
else
break;
}
}
void heapsort(vector<int> &num)
{
if (num.size() <= 1)
return;
for (int i = 1; i < num.size(); i++)
{
heapInsert(num, i);//建立最大堆
}
for (int i = num.size() - 1; i >= 1; i--)
{
swap(num[0], num[i]);
heapDown(num, i);
}
}