快速排序的基本思想:通过一趟排序算法将待排序的数据分割成独立的两个部分,其中一部分数据的关键字均比另一部分的关键字小,则可以分别对这两端数据今次昂排序,以达到整个序列有序。
详细描述:
- 从数列中挑出一个元素,称为“基准”
- 重新排序数列,所有元素比基准值小的摆放在基准前面,所有元素比基准大的摆在基准的后面。在这个分区退出后,该基准就处于数列的中间位置。
- 递归(或非递归)把小于基准值元素的子数列和大于基准值元素的子数列排序。
时间复杂度:平均时间复杂度:O(nlogn) 最坏的情况下:O(n^2) 最好的情况:O(nlogn)
空间复杂度:O(logn)
下面是递归代码:
int Quicksortonce(int *ar, int left, int right)
{
if (ar == NULL )
{
return -1;
}
int i = left; int j = right;
int tmp = ar[left];
while (i < j)
{
while (i < j && ar[j] > tmp)
{
j--;
}
if (i == j)
{
break;
}
ar[i] = ar[j];
while (i < j&& ar[i] < tmp)
{
i++;
}
if (i == j)
{
break;
}
ar[j] = ar[i];
}
ar[i] = tmp;
return i;
}
void quickSort(int *ar, int left, int right)
{
int pos = Quicksortonce(ar, left, right);
if (pos - left > 1)
{
quickSort(ar, left, pos - 1);
}
if (right - pos > 1)
{
quickSort(ar, pos + 1, right);
}
}
int main()
{
int ar[] = { 9, 5, 11, 14, 32, 16, 8, 23, 2 };
quickSort(ar, 0, 8);
for (int i = 0; i < 9; i++)
{
cout << ar[i] << " ";
}
cout << endl;
return 0;
}
下面是非递归代码:
int Oncesort(int *ar, int left, int right)
{
int i = left, j = right;
int tmp = ar[i];
while (i < j)
{
while (i < j && tmp < ar[j])
{
j--;
}
if (i == j)
{
break;
}
ar[i] = ar[j];
while (i < j && tmp > ar[i])
{
i++;
}
if (i == j)
{
break;
}
ar[j] = ar[i];
}
ar[i] = tmp;
return i;
}
void q_sort(int *ar, int left, int right)
{
std::stack<int> s;
s.push(left);
s.push(right);
while (!s.empty())
{
right = s.top();
s.pop();
left = s.top();
s.pop();
int pos = Oncesort(ar, left, right);
if (pos + 1 < right)
{
s.push(pos + 1);
s.push(right);
}
if (pos - 1 > left)
{
s.push(left);
s.push(pos - 1);
}
}
}
void Quicksort(int *ar,int len)
{
q_sort(ar, 0, len - 1);
}
int main()
{
int ar[] = { 9, 5, 11, 14, 32, 16, 8, 23, 2 };
int len = sizeof(ar) / sizeof(ar[0]);
Quicksort(ar,len);
for (int i = 0; i < len; i++)
{
cout << ar[i] << " ";
}
cout << endl;
return 0;
}