我遇到了这样一个算法问题:我需要让Quicksort像这样工作:
1)奇数的数组索引应从最小到最大
排序2)甚至索引应该从最大到最小排序。
所以,如果我们有阵列:2 5 1 3 4 0 6 2 5, 我们应该得到像:6 0 5 2 4 3 2 5 1
这是我在C中实现的快速排序:
void quicksort(int tab[], int start, int end) {
int i=start;
int j=end;
int x=tab[(i+j)/2];
do {
while(tab[i]<x) i++;
while(tab[j]>x) j--;
if(i<=j) {
int tmp=tab[i];
tab[i]=tab[j];
tab[j]=tmp;
i++;
j--;
}
} while(i<=j);
if(start<j) quicksort(tab,start,j);
if(i<end) quicksort(tab,i,end);
}
是否可以只使用一个快速排序,或者我应该尝试创建两个函数:一个是奇数索引,另一个是偶数索引?
答案 0 :(得分:1)
是否可以只使用一个快速排序,或者我应该尝试创建两个函数:一个是奇数索引,另一个是偶数索引?
quick sort
通常用于对升序或降序顺序中的元素进行排序,因此我认为仅对元素进行排序并不有用必需的模式(既不是升序也不是降序,甚至在答案数组中也没有保证特定的模式)仅使用quick sort
。在我看来,创建一个额外的自定义函数说
required_sort()
并根据需要对元素进行排序以及qucksort()
的帮助(在我的情况下,它按升序排序)将是最好的方式
void required_sort(int array[], int size_of_array)
{
int no_of_even_elements, no_of_odd_elements
if(size_of_array%2 == 0)
{
no_of_even_elements = no_of_odd_elements = n/2;
}
else
{
no_of_even_elements = (n/2)+1;
no_of_odd_elements = n/2;
}
int even[no_of_even_elements], odd_even[elements];
//inserting elements into new arrays
for(int index=0; index < size_of_array; index++)
{
if(index%2 == 0)
{
even[index/2] = array[index];
}
else
{
odd[index/2] = array[index];
}
}
//call quicksort function to sort the even[] array in ascending order
//call quicksort function to sort the odd[] array in ascending order
for(int index=0; index < size_of_array; index++)
{
if(index%2 == 0)
{
array[index] = even[(no_of_even_elements)-(index/2)];
}
else
{
array[index] = odd[index/2];
}
}
}
required_sort
的解释:
size_of_array
是否甚至或奇数 如果size_of_array
甚至那么奇数索引和偶数索引的元素数量相等。所以
no_of_even_elements = no_of_odd_elements = n/2
如果size_of_array
奇数,那么在奇数索引和偶数索引处有相同数量的元素。所以
no_of_even_elements = (n/2)+1
no_of_odd_elements = n/2
再创建两个数组。说odd[no_of_odd_elements]
和even[no_of_even_elements]
quicksort()
(按升序排列)对两个数组进行排序现在使用for
循环以这种方式更新原始array[]
的值:
for(int index=0; index < size_of_array; index++)
{
if(index%2 == 0)
{
array[index] = even[(no_of_even_elements)-(index/2)];
}
else
{
array[index] = odd[index/2];
}
}
希望这有助于:)
答案 1 :(得分:0)
您可以参数化快速排序算法,以支持(1)基于步长的部分排序和(2)排序方向。
void quicksort2(int tab[], int start, int end, int step, int (*comparer)(int, int))
引入参数step
,用于访问远离step
和start
的{{1}}元素的元素
每当更改索引时,请使用步长而不是end
:1
,i+=step;
等等。
计算枢轴的中间元素变得稍微复杂一些,以支持步长>&gt;的不均匀索引。 1:j-=step;
int mid = (end / step - start / step) / 2 * step + start; int x=tab[mid];
和start
索引必须是end
分开的倍数。
将比较更改为step
函数,而不是原生comparer
和<
运算符用法
比较器函数应返回>
的负值和a < b
的正值。用法:b < a
全部放在一起:
while(comparer(tab[i],x) < 0) // ...
我试图坚持你的初始本地快速排序实现,所以这段代码看起来应该很熟悉。
这可用于执行所需的排序,如下所示:
定义升序和降序排序的比较器函数。
void quicksort(int tab[], int start, int end, int step, int (*comparer)(int, int))
{
int i=start;
int j=end;
int mid = (end / step - start / step) / 2 * step + start;
int x=tab[mid];
do {
while(comparer(tab[i],x) < 0) i+=step;
while(comparer(tab[j],x) > 0) j-=step;
if(i<=j) {
int tmp=tab[i];
tab[i]=tab[j];
tab[j]=tmp;
i+=step;
j-=step;
}
} while(i<=j);
if(start<j) quicksort(tab,start,j, step, comparer);
if(i<end) quicksort(tab,i,end, step, comparer);
}
为两个子排序调用两次快速排序
int smaller(int a, int b)
{
return a - b;
}
int bigger(int a, int b)
{
return b - a;
}
小心获取开始和结束索引,或者在快速排序功能中为它们添加健全性检查