#include <iostream>
#include <stack>
using namespace std;
void Swap(int &a, int &b)
{
int p = a;
a = b;
b = p;
}
void print(int* arry, int num)
{
int i;
for(i = 0; i < num; i++)
cout << arry[i] << " ";
cout << endl;
}
//递归实现快速排序
void my_qsort(int *arry, int left, int right)
{
if(!arry || left < 0 || right < 0)
return;
int i, j;
if(left < right)
{
i = left;
j = right;
int x = arry[i];
while(i < j)
{
while((i < j) && (arry[j] > x)) --j; //从右向左寻找比x小的数
while((i < j) && (arry[i] < x)) ++i; //从左向由寻找比x大的数
Swap(arry[i], arry[j]);
}
arry[i] = x;
my_qsort(arry, left, i - 1);
my_qsort(arry, i + 1, right);
}
}
int partition(int *arry, int left, int right)
{
int x = arry[left];
int i, j;
i = left;
j = right;
while(i < j)
{
while((i < j) && (arry[j] > x)) --j;
while((i < j) && (arry[i] < x)) ++i;
Swap(arry[i], arry[j]);
}
arry[i] = x;
return i;
}
//非递归实现快速排序
void my_qsort2(int *arry, int left, int right)
{
if(!arry || left < 0 || right < 0)
return;
stack<int> stk;
if(left < right)
{
int mid = partition(arry, left, right);
if(left < mid - 1){
stk.push(left);
stk.push(mid - 1);
}
if(right > mid + 1){
stk.push(mid + 1);
stk.push(right);
}
while(!stk.empty())
{
int h = stk.top();
stk.pop();
int l = stk.top();
stk.pop();
mid = partition(arry, l, h);
if(l < mid - 1){
stk.push(l);
stk.push(mid - 1);
}
if(h > mid + 1){
stk.push(mid + 1);
stk.push(h);
}
}
}
}
//非递归实现查找无序数组中第k大的数
/* 利用快速排序的思想实现查找第k大的数:快速排序每次选择一个数作为关键数,一次排序这个关键数
的左边都是比它小的数,右边都是比它大的数,所以只要比较下这个关键数所在的下标,就可以知道它是
所有数字中的第几大的数了 */
int find_k_max(int *arry, int num, int k)
{
if(!arry || num <= 0 || k <= 0 || k > num)
return -0xff;
int i, j;
i = 0;
j = num - 1;
int x;
while(1)
{
x = arry[i];
while(i < j)
{
while((i < j) && (arry[j] > x)) --j; //从右向左寻找比x小的数
while((i < j) && (arry[i] < x)) ++i; //从左向由寻找比x大的数
Swap(arry[i], arry[j]);
}
arry[i] = x;
/* 一次快排完毕,这个中间数字是不是要寻找的数 */
if(num - i == k){ //如果是寻找第k小的数,则条件为 i == k
break;
}
else if(num - i < k){ //如果num - i < k则说明我们要寻找的第k大的数在这个中间数字的左边
i = 0;
j = i - 1;
}else{
i++;
j = num - 1;
}
}
return x;
}
//递归实现查找无序数组中第k大的数
int find_k_max2(int *arry, int num, int k)
{
if(!arry || num <= 0 || k <= 0 || k > num)
return -0xff;
int i, j;
i = 0;
j = num - 1;
int x = -0xff;
if(i < j)
{
x = arry[0];
while(i < j)
{
while((i < j) && (arry[j] > x)) --j; //从右向左寻找比x小的数
while((i < j) && (arry[i] < x)) ++i; //从左向由寻找比x大的数
Swap(arry[i], arry[j]);
}
arry[i] = x;
if(num - i == k){
return x;
}
else if(num - i < k){
return find_k_max2(arry, i - 1, k);
}else{
return find_k_max2(arry + i + 1, num - i - 1, k);
}
}
return x;
}
int main()
{
int a[10] = {5, 1, 0, 9, 4, 3, 2, 7, 6, 8};
print(a, 10);
#if 1
cout << "第1大的数为:" << find_k_max2(a, 10, 1) << endl;
print(a, 10);
cout << "第2大的数为:" << find_k_max2(a, 10, 2) << endl;
print(a, 10);
cout << "第3大的数为:" << find_k_max2(a, 10, 3) << endl;
print(a, 10);
#endif
//my_qsort2(a, 0, 9);
my_qsort(a, 0, 9);
print(a, 10);
return 0;
}
快排算法及利用快排思想寻找第k大(小)的数
最新推荐文章于 2023-06-30 14:54:18 发布