【发布时间】:2012-03-29 19:30:57
【问题描述】:
这里是通过将数组分成5组来实现中位数的伪代码
select(int A[],int first, int last, int i) {
n = last - first + 1; /* n is the number elements to select from */
if (i > n) {return ERROR;} /* there is no ith smallest element */
if( n < = 100 ) {
/********************* For Small n *********************/
Run selection on A[first..last] taking at most n(n-1)/2 < 50n comparisons;
swap A[first+i-1] with A[first] /* put ith smallest in A[first] */
}
else /* n > 100 */ {
/********** main recursion *************************/
numGroups = n / 5; /* integer division, round down */
for group = 0 to numGroups-1 do {
shift = group*5;
/* A[first+shift] is the start of the group, A[first+shift+4] is end of group */
find median of A[first+shift .. first+shift+4] and swap it into A[first + group];
} /* for group */;
lastMedian = first+numGroups-1;
/* now the medians of the numGroups groups are all A[first .. lastMedian] */
/****** the first recursive call to find median of medians ******/
select(A, first, lastMedian, numGroups/2);
/* now median of medians is in slot A[first] */
/*********** partition array *********************/
k = partition(A,first, last); /* See partition on page 146 of text */
/* now k is the index where the median of median winds up, the smaller elements */
/* will be in A[first..k-1] and larger elements will be in A[k+1..last] */
/************ where is the ith smallest element? ********/
if (k == first + i -1) {
/* ith smallest is the median of medians in A[k] */
swap A[k] and A[first] and return
} else if (k > = first + i -1) {
/* second recursion to find ith smallest among the "small" keys in A[first..k-1] */
select(A, first, k-1, i);
} else /* k < first + i -1 */ {
/* second recursion to find the proper element among the "large" keys */
numSmaller = k-first+1; /* the number of "smaller" keys not recursed on */
newi = i - numSmaller;
/* the ith smallest of A[first..last] is the newi smallest of A[k+1..last] */
select(A, k+1, last, newi);
/* ith smallest now in A[k+1], put it in A[first] */
swap A[k+1] and A[first];
} /* if k - second else */
} /* if n - else part */
} /*select */
我有两个问题:
-
第一个与分区代码有关,这里我们只给出数组及其边界,没有指示枢轴元素,那么这个分区代码应该是什么样子?我们应该选择枢轴索引和枢轴元素为:
int pivotindex=(end-begin)/2 int pivot values=a[pivotindex];还是随机选择?
如何输出选中的中位数?
通常语言无关紧要,但如果示例能用 C++ 显示就更好了。
【问题讨论】:
-
谁看到了投反对票的理由?
-
不是我,但我理解反对意见,您粘贴了一大段代码(尽管注释丰富),但实际上并没有说明 select 函数本身应该做什么。 “中位数三的中位数”到底是什么?
-
没有中位数,没有三个地方写了这个名字,我弄错了
-
您应该说明要解决的问题,并且当您可以访问您的笔记和教科书来解决任务时,其他人则没有,因此 参见第 146 页上的分区几乎没用。如果这是家庭作业,你应该这样标记它。您基本上是在要求人们在没有任何上下文信息的情况下为您解决作业,这是拒绝投票的一个很好的理由。由于缺乏答案,只是太多不需要的信息难以消化,以及缺乏重要信息。你应该真正解决这个问题,而不是把它扔在这里。
-
如伪代码所述,第一个问题的答案在教科书的第 146 页。只需谷歌搜索“参见第 146 页上的分区”即可提供 C++ 和 java 解决方案。
标签: algorithm median-of-medians