赞
踩
定义数组的头部为一个基准,首先从基准的右边比较,交换基准数字;然后从基准的左边比较,交换基准数字。
使基准的左右两边分别都是比基准小和比基准大的数字,完成一次排序。
然后从左右两边分别重新定义新的基准,继续比较排序。
持续减少比较长度,直至左右两边均剩余一个数字,此时完成整个数组的排序。
static int Partition(int* arr,int low,int high)//一次快速排序,时间复杂度O(n) { int tmp = arr[low];//备份基准值 while (low < high)//当low大于等于high时,结束循环 { while (low < high && arr[high] >= tmp)//从最后面high开始到low之间,寻找比基准值tmp小的数字,将其移动到前面的空缺位上 { high--;//如果arr[high]大于等于基准tmp,向前移动 } if (low == high)//当low和high相等时说明没有比基准tmp小的数字,跳出整个循环 { break; } else//否则,说明arr[high]小于基准tmp,将high的值置于low的位置上 { arr[low] = arr[high]; } while (low < high && arr[low] <= tmp)//从最前面low开始到high之间,寻找比基准值tmp大的数字,将其移动到后面的空缺位上 { low++;//如果arr[low]大于等于基准tmp,向后移动 } if (low == high)//当low和high相等时说明没有比基准tmp大的数字,跳出整个循环 { break; } else//否则,说明此位置的arr[low]大于基准tmp,将low的值置于high的位置上 { arr[high] = arr[low]; } } arr[low] = tmp;//最后将基准值tmp,归位,此时基准值的两边都是比基准值小或比基准值大的数字 return low;//返回基准值的位置,用于判断边界 }
static void Quick(int* arr, int low, int high)//排序边界,递归 { int par = Partition(arr, low, high); if (low + 1 < par)//继续排序划分,直至左边剩余1位数字 { Quick(arr, low, par - 1); } if (par < high - 1)//继续排序划分,直至右边剩余1位数字 { Quick(arr, par + 1, high); } } void QuickSort(int* arr, int len)//快速排序(递归) { Quick(arr, 0, len-1);//调用接口,参数列表不同 }
创建一个大小为4个整型数字的数组缓冲区
因为:每次最多进两组数据,即1个基准的左边和右边都存在超过1个数字需要排序,之后读出数据后再存放数据会直接覆盖,这样可以优先将基准一边的数据先处理完,然后再读出数据处理另一边。
void QuickSort(int* arr, int len)//快速排序 { int buff[4];//每次最多进两组数据即,1个基准的左边和右边都存在超过1个数字需要排序,之后读出数据后再存放数据会直接覆盖 int* stack = buff; assert(stack != NULL); int top = 0;//栈顶指针,当前可以存放数据的下标 int low = 0; int high = len - 1; int par = Partition(arr, low, high); while (top >= 0) { if (low + 1 < par) { stack[top++] = low; stack[top++] = par - 1; } if (par < high - 1) { stack[top++] = par + 1; stack[top++] = high; } high = stack[--top]; low = stack[--top]; if (top < 0) { break; } par = Partition(arr, low, high); } }
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。