本篇博客主要介绍快速排序的过程,因为网上看了很多,感觉有些博主真的是在误导学者,画的图是冒泡或者其他排序的图,一本正经的讲着快排,真的自欺欺人。这不说,当我开心的看完人家的文字介绍,发现代码写的更是一塌糊涂,白白浪费我的复习时间,算了,自己动手丰衣足食。
- 快速基本思想:
通过一次排序将整个无序表分成相互独立的两部分,其中一部分的数据都比另一部分包含的数据小,然后继续沿用此种方法分别对两部分进行同样的操作,直到每一部分不可再分,所得到的整个序列就成为有序序列。
例如序列:49 38 65 97 76 13 27 49
-
设置两个指针low和high,分比为指向无序表的表头和表尾
-
我们以第一个数49为基准,先由high指针从右向左依次遍历,找到第一个比49小的数字,即就是27,和low所指向的数字进行交换
-
第二步从low开始,从左往右开始找比49大的数字,即就是65,然后和high指向的数字进行交换
-
第三步继续从high开始,找比49小的数字,即就是13,然后和low所指向的数字进行交换
-
第四步从low向右遍历,找比49大的数字,即就是97,然后和high所指向的数字进行交换
当low和high都指向同一位置的时候,第一趟排序就已经完成,以49为中心,将无序表分成了两个部分,再用同样的方法,对左右两个部分进行排序。
#include <iostream>
#include <stdlib.h>
#include <stack>
#include <assert.h>
using namespace std;
void QuickSort1(int *a,int left, int right)
{
if (left < right)
{
int low = left;
int high = right;
int temp = a[low];
while (low != high)
{
while (low < high&&a[high] >= temp)
high--;
if (a[high] < temp)
{
int ret = a[high];
a[high] = a[low];
a[low] = ret;
}
while (low < high&&a[low] <= temp)
low++;
if (a[low] > temp)
{
int ret = a[high];
a[high] = a[low];
a[low] = ret;
}
}
a[low] = temp;
QuickSort1(a, left, low - 1);
QuickSort1(a, low + 1, right);
}
}
void prit(int *a,int n)
{
for (int i = 0; i < n; i++)
{
cout << a[i] << " ";
}
cout << endl;
}
int main()
{
int a[9] = { 49, 38, 65, 97, 76, 13, 27, 49 };
cout << "原数组是:" << endl;
prit(a, 8);
cout << "递归快速排序后:" << endl;
QuickSort1(a, 0, 7);
prit(a, 8);
system("pause");
return 0;
}
- 非递归就要用到栈了,思路跟递归相似,直接附上代码
#include <iostream>
#include <stdlib.h>
#include <stack>
#include <assert.h>
using namespace std;
int partition(int* a, int left, int right)
{
double x = a[right];
int i = left - 1, j = right;
for (;;)
{
while (a[++i] < x) {}
while (a[--j] > x) { if (j == left) break; }
if (i < j)
swap(a[i], a[j]);
else break;
}
swap(a[i], a[right]);
return i;
}
void Quick_Sort2(int *arr, int len)
{
//1.申请一块内存当栈
//2.进行一次快速排序,找到基准
//3.把左边 右边的数对进行入栈
//4.取出数据进行一趟快速排序
//5.top>0
int *stack = (int *)malloc(sizeof(int) * len);//定义栈的大小
assert(stack != NULL);
int top = 0;
int low = 0;
int high = len - 1;
int par = partition(arr, low, high);
if (par > low + 1)//左边有两个数据以上数时 入栈
{
stack[top++] = low;
stack[top++] = par - 1;
}
if (par < high - 1)//右边左边有两个数据以上数时 入栈
{
stack[top++] = par + 1;
stack[top++] = high;
}
while (top > 0)//出栈 栈不空,需要取两个数据出来排序
{
high = stack[--top];
low = stack[--top];
par = partition(arr, low, high);
if (par > low + 1)
{
stack[top++] = low;
stack[top++] = par - 1;
}
if (par < high - 1)
{
stack[top++] = par + 1;
stack[top++] = high;
}
}
free(stack);
stack = NULL;
}
void prit(int *a,int n)
{
for (int i = 0; i < n; i++)
{
cout << a[i] << " ";
}
cout << endl;
}
int main()
{
int a[9] = { 49, 38, 65, 97, 76, 13, 27, 49 };
cout << "原数组是:" << endl;
prit(a, 8);
cout << "非递归快速排序后:" << endl;
Quick_Sort2(a, 8);
prit(a, 8);
system("pause");
return 0;
}