目录
递归实现
思路如下:
1.选择一个值作为基准值key(一般选最左边或最右边,在这里选最左边)。
2.定义L,R(分别为待排序序列最左边与最右边元素的下标),L从左往右走,R从右往左走(若选最左边为key,R先走;选最右边为key,L先走)。
3.R从右往左走遇到比key小的停下来,接着L从左往右走,遇到比key大的停下来。然后交换R,L对应数组中的值。
4.重复上一步操作,直至L,R二者相遇。将相遇点对应的值与key对应的值交换,此时相遇点左边的值均小于相遇点所对应的值,右边的值均大于相遇点所对应的值。
5.相遇点将待排序序列分为两个子序列,用递归的方式重复上述操作。
6.当左右序列只有一个元素的时候排序完成。
void Swap(int* x, int* y) { int tmp; tmp = *x; *x = *y; *y = tmp; } //arr为待排序数组,start为待排序数组第一个元素的下标,end最后一个元素的下标 void QuickSort(int* arr,int start,int end) { int L = start;//Left int R = end;//Right int key = L;//选择最左边元素为key if (L >= R)//序列不存在或者只有一个元素 return; while (L<R) { //R先走,找小 while (L<R&&arr[R]>=arr[key]) { R--; } //L先走,找大 while (L < R && arr[L] <= arr[key]) { L++; } Swap(&arr[L], &arr[R]);//L,R都停下来了,交换 } //退出循环,L,R已经相遇 Swap(&arr[key],&arr[L]);//交换相遇处与key处的值 //此时key左边的值均小于key处的值,右边的值均大于key处的值 QuickSort(arr,start,L-1); QuickSort(arr,R + 1, end); }
用栈的思想实现
不使用递归进行快速排序,需要将单趟排序进行分装
int PartSort(int* arr, int start, int end) { int L = start;//Left int R = end;//Right int key = L;//选择最左边元素为key if (L >= R)//序列不存在或者只有一个元素 return L; while (L < R) { //R先走,找小 while (L < R && arr[R] >= arr[key]) { R--; } //L先走,找大 while (L < R && arr[L] <= arr[key]) { L++; } Swap(&arr[L], &arr[R]);//L,R都停下来了,交换 } //退出循环,L,R已经相遇 Swap(&arr[key], &arr[L]);//交换相遇处与key处的值 //此时key左边的值均小于key处的值,右边的值均大于key处的值 return L;//新的key——L,R相遇的位置 }
思路如下:
1.先将待排序序列最左边与最右边元素的下标入栈。
2.在栈不为空的情况下进入循环,读取栈中数据记作L,R。
3.将L,R传入部分排序函数,并返回一个将原序列分为左右两部分的下标,记作k。
4.判断左序列是否需要排序,若需要的话将左序列的L,R入栈。右序列进行一样操作。
5.反复执行上述操作,直至栈为空。
void QuickSort(int *arr,int start,int end) { struct Stack ps;//建立栈 StackInit(&ps);//栈的初始化 StackPush(&ps, start); StackPush(&ps, end); while (!StackEmpty(&ps))//栈不为空时进入循环 { int R = StackTop(&ps);//读取R StackPop(&ps);//栈顶出栈 int L = StackTop(&ps);//读取L StackPop(&ps);//栈顶出栈 int key = PartSort(arr,L,R); if (L < key-1)//左序列还要进行排序 { StackPush(&ps, L);//左序列L入栈 StackPush(&ps, key-1);//左序列R入栈 } if(R > key+1)//右序列还要进行排序 { StackPush(&ps, key + 1);//右序列L入栈 StackPush(&ps, R);//右序列R入栈 } } }