简体   繁体   English

结合QuickSort和中值选择算法

[英]Combine QuickSort and Median selection algorithm

I want to modify QuickSort (in Java) so that every time Partition is called, the median of the proportioned array is used as the pivot. 我想修改QuickSort(在Java中),以便每次调用Partition时,将比例数组的中位数用作枢轴。

I have a median selection algorithm in Java that returns the kth smallest element, in this case the median. 我在Java中有一个中位数选择算法,该算法返回第k个最小元素,在这种情况下为中位数。 I have tons of quicksort algorithms in java that all work by themselves and sort an array. 我在Java中有大量的快速排序算法,它们全靠自己工作并对数组进行排序。 Unfortunately I can't combine those two in order to achieve the above... Everytime I try it i usually get stackoverflow erros. 不幸的是,我无法将两者结合起来以实现上述目标。每次尝试时,我通常都会遇到stackoverflow错误。

Can anybody show me code to see how it can be done? 谁能给我看代码以查看如何完成?

Thanks 谢谢

EDIT: For example this is a median selection algorithm that I have tried to use. 编辑:例如,这是我尝试使用的中位数选择算法。

public int quickSelect(int[] A, int p, int r, int k) {
    if (p==r) return A[p];
    int q = Partition(A,p,r);
    int len = q-p+1;

    if (k == len) return A[q];
    else if (k<len) return Select(A,p,q-1,k);
    else return Select(A,q+1,r,k-len);
}

public int partition(int[]A, int p, int r) {
    int x = A[r];
    int i = p-1;
    for (int j = p; j<=r-1; j++) {
        if (A[j] <= x) {
            i++;
            swap(A,i,j);
        }
    }
    swap(A,i+1,r);
    return i+1;
}

It works by itself but when I try to call quickSelect through quicksort's partition function to return the pivot to be used, it doesn't work. 它本身可以工作,但是当我尝试通过quicksort的分区函数调用quickSelect来返回要使用的数据透视表时,它不起作用。 Obviously I'm doing something wrong but I don't know what. 显然我做错了,但我不知道该怎么办。 Unfortunately on the Internet I haven't found any algorithm, even in pseudocode, that would combine a median selection with quicksort. 不幸的是,在Internet上,我什至找不到任何算法,即使是伪代码,也无法将中位数选择与快速排序结合在一起。

The standard way to get the median is to sort the data. 获取中位数的标准方法是对数据进行排序。 And you want to sort the data by partitioning on the median. 您想通过对中位数进行分区来对数据进行排序。 This seems very chicken and egg to me. 这对我来说似乎是鸡和鸡蛋。

Could you elaborate on why you want to partition/pivot on the median? 您能否详细说明为什么要在中位数上进行分区/数据透视?

What you are looking for is the Selection Algorithm. 您正在寻找的是选择算法。 Here's a link with pseudocode . 这是伪代码链接

From the link: 从链接:

In computer science, a selection algorithm is an algorithm for finding the kth smallest number in a list 在计算机科学中,选择算法是一种用于在列表中找到第k个最小数字的算法

To find the median you want to find the k=floor((n+1)/2) smallest number in the list where n is the size of the list. 要查找中位数,您想要在列表中找到k = floor((n + 1)/ 2)最小的数字,其中n是列表的大小。

Note that in PARTITION the pivot is A[r] . 请注意,在PARTITIONpivotA[r]

public int QUICKSORT2(int[] A, int p, int r) {
    if (p<r) {
        int median=Math.floor((p + r) /2) - p + 1
        int q=SELECT(A, p, r, median)
        q=PARTITION2(A, p, r, q)
        QUICKSORT2(A, p, q-1)
        QUICKSORT2(A, q+1, r)
    }
}

public int PARTITION2(int[]A, int p, int r, int q) {
    int temp = A[r];
    A[r]=A[q];
    A[q]=temp;
    return PARTITION(A, p, r)
}

You can use this ... 您可以使用此...

int Select(int array[],int start, int end,int k){

if(start==end){
    return start;
}

int x=array[end];
int i=start-1;
for(int j=start;j<=end-1;j++){
    if(array[j]<x){
        i++;
        Swap(array+i,array+j);
    }
}
i++;
Swap(array+i,array+end);

if(i==k){
    return i;
}
else if(i>k){
    return Select(array,start,i-1,k);
}
else{
    return Select(array,i+1,end,k);
}

} }

Select will partition array on kth smallest element in array; 选择会将数组分区到数组中第k个最小元素上;

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM