C++快速排序

C++快速排序

通过一趟排序将要排序的数据分割成两部分,其中一部分的所有数据都比另外一部分的所有数据都要小,然后再按此步骤对这两部分的数据进行快速排序,整个排序的过程可以使用递归进行。以此达到整个数据变成有序序列。

快速排序通过多次比较和多次交换来实现排序,排序历程:

(1)首先设定一个分界值,通过该分界值将数组分成左右两部分(一般分界值为第一个)

(2)将大于或等于分界值的数据集中到数组的右边,小于分界值的数据集中到数组的左边。这时,左边部分各元素小于或等于分界值,而右边部分各元素都大于或等于分界值。

(3)分别对左边和右边进行相同操作,继续寻找分界值左边和右边类似的操作,类似与递归操作。

(4)重复上述过程,递归左边和右边分别排序完成后,整个数组排序也就完成。

(一)左右指针

第一趟排序:

C++快速排序_第1张图片

排序全过程:

C++快速排序_第2张图片

#include
using namespace std;

void swap(int *a, int *b) {
	int temp = *a;
	*a = *b;
	*b = temp;
}
int partition(int low, int high, int a[]) {
	int privotKey = a[low];
	while (low < high) {
		while (low < high&&a[high] >= privotKey) --high;
		swap(&a[low], &a[high]);
		while (low < high&&a[low] <= privotKey) ++low;
		swap(&a[low], &a[high]);
	}
	return low;
}
void quickSort(int low, int high, int a[]) {
	if (low < high) {
		int privotLoc = partition(low, high, a);
		quickSort(low, privotLoc - 1, a);
		quickSort(privotLoc + 1, high, a);
		
	}
}

int main() {

	int array[] = { 49,38,65,97,76,13,27,49 };
	for (int i = 0; i <= 7; i++) {
		cout << array[i] << " ";
	}
	cout << endl;
	quickSort(0, 7,array);
	for (int i = 0; i<=7; i++) {
		cout << array[i] << " ";
	}
	system("pause");
	return 0;
}

(二)挖坑法

1.定义两个指针left指向起始位置,right指向最后一个元素的位置,然后指定一个基数key(right),作为坑
2.left寻找比基数(key)大的数字,找到后将left的数据赋给right,left成为一个坑,然后right寻找比基数(key)小的数字,找到将right的数据赋给left,right成为一个新坑,循环这个过程,直到begin指针与end指针相遇,然后将key返回给那个坑(最终:key的左边都是比key小的数,key的右边都是比key大的数),然后进行递归操作。

C++快速排序_第3张图片

void quickSort(int left, int right, int a[])
{
	if (left >= right) return;
	//以第一个元素为基准,执行一趟划分
	int i = left, j = right;
	int t = a[left];
	while (i < j)
	{
		while (i < j && a[j] >= t) //从右向左扫描,选取第一个小于t的元素交换
			j--;
		a[i] = a[j];
		while (i < j && a[i] <= t) //再从左往右扫描,选取第一个大于t的元素交换
			i++;
		a[j] = a[i];
	}
	a[i] = t;
	//递归执行划分
	for (int i = 0; i <= 7; i++) {
		cout << a[i] << " ";
	}
	cout << endl;
	quickSort(left, i - 1, a);
	quickSort(i + 1, right, a);
}

(三)前后指针法

1.定义两个指针,一前一后,cur(前)指向起始位置,prev(后)指向cur的前一个位置;选择数组最后一个元素作为key(right)
2.实现过程:cur找比key小的数,prev在cur没有找到的情况下,一直不动(即保证prev一直指向比key大的数);直到cur找到比key小的数(+ +prev && prev != cur时)然后++cur,prev仍然不动。
3.直到cur走到right前一个位置,终止循环。最后++prev,交换prev和right的值。返回中间位置prev。最后再继续递归。

C++快速排序_第4张图片

int QuickSort_Cur(int* a,int left,int right)
{
    int cur = left;
    int prev = left -1;
    int key = a[right];
    while(cur < right)
    {
        if(a[cur] < key && ++prev != cur)
        {
            swap(a[cur],a[prev]);
        }
        ++cur;
    }
    swap(a[++prev],a[right]);
    return prev;
}

快速排序——非递归

利用栈保存左右区间

1. 左右区间入栈(先右后左)
2. 取栈顶元素,出栈
3. 排序
4. 入栈,先右后左(直到栈为空,停止循环)

void QuickSortNOR(int* a,int left,int right)
{
    stack s;
    if(left < right)
    {
        s.push(left);
        s.push (right);
    }
    while(!s.empty ())
    {
        int right = s.top ();
        s.pop ();
        int left = s.top ();
        s.pop();
        int div =  PartSort1(a,left,right);
        if((right-left +1) < 20)  //小区间时不再递归
        {
            InsertSort(a+left,right-left+1);
        }
        else
        {
            if(left < div-1)
            {
                s.push (left);
                s.push (div-1);
            }
            if(div+1

 

你可能感兴趣的:(算法,C++)