算法分析-中位数和顺序统计学

 

 1 Array.prototype.findMaxAndMin = function () {
 2 
 3     if (this.length == 0) return {min: null, max: null};
 4 
 5     var min, max, index = 0; //两个数之间的最大值,最小值 还有下标;
 6     var temp_max, temp_min = 0;
 7 
 8     //偶数
 9     if (this.length % 2 == 0) {
10         if (this[0] > this[1]) {
11             max = this[0];
12             min = this[1];
13         } else {
14             min = this[0];
15             max = this[1];
16         }
17         index = 2;
18     } else {  //奇数
19         min = this[0];
20         max = this[0];
21         index = 1;
22     }
23 
24     //采用迭代
25     while (index < this.length - 1) {
26         if (this[index] < this[index + 1]) {
27             temp_max = this[index + 1];
28             temp_min = this[index];
29         } else {
30             temp_max = this[index];
31             temp_min = this[index + 1];
32         }
33         max = temp_max > max ? temp_max : max;
34         min = temp_min < min ? temp_min : min;
35         index += 2;
36     }
37 
38     return {min: min, max: max};
39 };
40 
41 var A = [16, 22, 2, 323320, 13, 3, 2321, 45546, 5766, 7, 23];
42 console.log(A.findMaxAndMin());

 

 1 Array.prototype.swap = function (i, j) {
 2     var temp = this[i];
 3     this[i] = this[j];
 4     this[j] = temp;
 5 };
 6 
 7 Array.prototype.RANDOM_PARTITION = function (p, r) {
 8     console.log("p", p, "r", r);
 9     var random = Math.round(p + Math.random() * (r -p));
10 
11     this.swap(random, r);
12     return this.PARTITION(p, r);
13 };
14 
15 Array.prototype.PARTITION = function (p, r) {
16     var x = this[r];
17     var i = p - 1;
18 
19     for (var j = p; j < r; j++) {
20         if (this[j] < x) {
21             this.swap(++i, j);
22         }
23     }
24     this.swap(r, ++i);
25     return i;
26 };
27 
28 Array.prototype.RONDOMIZED_SORT = function (p, r, i) {
29     if (p == r) return this[p];
30 
31     var q = this.RANDOM_PARTITION(p, r);
32 
33     var k = q - p + 1;  //计算A[p..q]一共有多少元素
34 
35     if (i == k)  return this[q];
36 
37     if (i < k) {
38         return arguments.callee.call(this, p, q - 1, i); //记住这里一定要加return 才会逐级往上返回。
39     } else {
40         return arguments.callee.call(this, q + 1, r, i - k); //因为所求在大端,我们已经知道k前面个数字是不符合的,所以要减去
41     }
42 };
43 
44 
45 var A = [1, 2, 3, 4, 5, 3, 2, 1, 0, -1];
46 
47 console.log(A.RONDOMIZED_SORT(0, A.length - 1, 9));

 

 

RANDOMIZED-SELECT 算法采用快速排序算法的思想。区别是,快速排序会递归地处理划分的两边,而 RANDOMIZED-SELECT 则只处理一边。所以快速排序的期望运行时间是 Θ(n lg n),而 RANDOMIZED-SELECT 的期望运行时间为 Θ(n)。

RANDOMIZED-SELECT 的最坏运行时间为 Θ(n2),即使是要选择最小元素也是如此。因为它是随机化的,该算法的平均情况性能较好。

 

9.2-1 证明:在RANDOMIZED-SELECT中,对长度为0的数组,不会进行递归调用。

看上面的代码,从RANDOMIZED-SELECT函数知,长度为0的数组 p=r,那么直接返回A[p].不做下面的随机划分和递归调用。

 

9.2-3 给出RANDOMIZED-SELECT的一个基于迭代的版本。

 

 1 Array.prototype.swap = function (i, j) {
 2     var temp = this[i];
 3     this[i] = this[j];
 4     this[j] = temp;
 5 };
 6 
 7 Array.prototype.RANDOM_PARTITION = function (p, r) {
 8 
 9     var random = Math.round(p + Math.random() * (r - 1 - p));
10     this.swap(random, r);
11     return this.PARTITION(p, r);
12 };
13 
14 Array.prototype.PARTITION = function (p, r) {
15     var x = this[r];
16     var i = p - 1;
17 
18     for (var j = p; j < r; j++) {
19         if (this[j] < x) {
20             this.swap(++i, j);
21         }
22     }
23     this.swap(r, ++i);
24     return i;
25 };
26 
27 Array.prototype.RANDOM_SELECT = function (p, r, i) {
28     var type = 0;
29     var q;  //q左边的都比q小,反之都大于等于
30     var k;  //A[p...r]子数组的元素个数
31 
32     while (true) {
33         if (p == r) break;
34         q = this.RANDOM_PARTITION(p, r);
35 
36         k = q - p + 1;
37 
38         if (k == i) {
39             type = 1;
40             break;
41         }
42 
43         if (i < k) {
44             r = q - 1;
45         } else {
46             p = q + 1;
47         }
48 
49     }
50     return type ? this[q] : this[p];
51 };
52 
53 
54 var A = [1, 2, 3, 4, 5, 3, 2, 1, 0, -1];
55 
56 console.log(A.RANDOM_SELECT(0, A.length - 1, 2));

 

下面给出一个更简介的代码:

 

 

var A = [100, 122, 223, 334, 445, 556, 556, 666, 777];
var B = [9, 9, 9, 10, 11, 12, 13, 14, 15];

function getMedian(A, B) {

    while (true) {
        var n = A.length;

        if (n > 1) {
            if (A[Math.floor(n / 2)] > B[Math.floor(n / 2)]) {
                A = A.slice(0, Math.floor(n / 2) + 1);
                B = B.slice(Math.floor(n / 2), n + 1);
            } else {
                B = B.slice(0, Math.floor(n / 2) + 1);
                A = A.slice(Math.floor(n / 2), n + 1);
            }
        } else {
            return A[0] < B[0] ? A[0] : B[0];
        }
    }
}
console.log(getMedian(A, B));

 

posted @ 2016-09-28 16:20  hdu胡恩超  阅读(739)  评论(0编辑  收藏  举报