C 快速排序中不同的奇偶排序
我遇到了这样一个算法问题:我需要进行快速排序,以便像这样工作: 1) 奇数数组的索引应该从最小到最大排序 2) 甚至索引也应该从最大到最小排序 如果我们有数组:2 5 1 3 4 0 6 2 5, 我们应该得到这样的结果:60 5 2 4 3 2 5 1 以下是我在C中对快速排序的实现:C 快速排序中不同的奇偶排序,c,sorting,quicksort,C,Sorting,Quicksort,我遇到了这样一个算法问题:我需要进行快速排序,以便像这样工作: 1) 奇数数组的索引应该从最小到最大排序 2) 甚至索引也应该从最大到最小排序 如果我们有数组:2 5 1 3 4 0 6 2 5, 我们应该得到这样的结果:60 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
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);
}
void快速排序(int选项卡[],int开始,int结束){
int i=开始;
int j=结束;
int x=制表符[(i+j)/2];
做{
而(表[i]x)j--;
如果(i)
是否可以只使用一个快速排序,或者我应该尝试创建两个函数:一个将对奇数索引进行排序,另一个将对偶数索引进行排序
quick sort
通常用于按升序或降序对元素进行排序,因此我认为仅使用quick sort
按所需模式(既不升序也不降序,甚至在应答数组中也不保证有特定模式)对元素进行排序是没有用的
在我看来,创建一个额外的自定义函数,比如说required\u sort()
,并根据需要在qucksort()
的帮助下对元素进行排序(在我的例子中,它是按升序排序的)将是最好的方法
如果数组的大小\u是奇数,那么奇数索引和偶数索引处的元素数相等
no_of_even_elements = (n/2)+1
no_of_odd_elements = n/2
再创建两个数组。比如说odd[no\u of奇数元素]
和偶数[no\u of偶数元素]
在第一个数组中,以奇数索引存储元素,在第二个数组中,以偶数索引存储元素
使用快速排序()
(按升序)对两个数组进行排序
现在使用for
循环更新原始数组[]
的值,方法如下:
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];
}
}
for(int index=0;index
希望这有帮助:)您可以参数化快速排序算法,以支持(1)基于步长的部分排序和(2)排序方向
void quicksort2(int tab[], int start, int end, int step, int (*comparer)(int, int))
引入一个参数step
,用于访问远离start
和end
的step
元素
每当索引更改时,使用步长而不是1
:i+=step;
,j-=step;
等等
为了支持步长大于1的不均匀索引,计算pivot的中间元素变得稍微复杂一些:int mid=(end/step-start/step)/2*step+start;int x=tab[mid];
开始
和结束
索引必须是步骤
的倍数
将比较更改为比较器
函数,而不是本机
运算符用法
比较器函数应为a
返回负值,为b
返回正值。用法:while(比较器(选项卡[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 values[] = { 2, 5, 1, 3, 4, 0, 6, 2, 5 };
quicksort(values, 0, 8, 2, &smaller);
quicksort(values, 1, 7, 2, &bigger);
注意正确设置开始索引和结束索引,或者在快速排序函数中为它们添加一个健全性检查如果所有其他操作都失败,请尝试编写两个函数,然后看看如何将它们合并为一个。在我看来,“一次完成”很难同时进行两种排序.Quicksort选择一个透视元素,然后将数据分为两部分:小于透视的元素和大于透视的元素。然后对这些集合进行递归排序。“小,偶数”元素集的大小(不一定)与“小,奇数”元素集的大小相同,“大,偶数”和“大,奇数”元素集的大小相同。因此,递归必须使用奇数和偶数的不同大小集,使用不同的“开始”和“结束”索引。只需调用qsort两次。调用原始函数两次,但函数内部只需使用索引即可。
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;
}
int values[] = { 2, 5, 1, 3, 4, 0, 6, 2, 5 };
quicksort(values, 0, 8, 2, &smaller);
quicksort(values, 1, 7, 2, &bigger);