顺序统计

一.最大值与最小值

 1 #include<iostream>
 2 using namespace std;
 3
 4 template<typename T>
 5 void MaxMin(T A[], int length, T &max, T &min)
 6 {
 7     if (A == NULL || length <= 0)
 8     {
 9         return;
10     }
11     int i;
12     if (length % 2 == 0)
13     {
14         i = 2;
15         if (A[0] > A[1])
16         {
17             max = A[0];
18             min = A[1];
19         }
20         else
21         {
22             max = A[1];
23             min = A[0];
24         }
25     }
26     else
27     {
28         max = A[0];
29         min = A[0];
30         i = 1;
31     }
32
33     for (; i < length; i += 2)
34     {
35         T cmax, cmin;
36         if (A[i] > A[i + 1])
37         {
38             cmax = A[i];
39             cmin = A[i + 1];
40         }
41         else
42         {
43             cmax = A[i + 1];
44             cmin = A[i];
45         }
46
47         if (max < cmax)
48         {
49             max = cmax;
50         }
51         if (min > cmin)
52         {
53             min = cmin;
54         }
55     }
56 }
57
58 int main()
59 {
60     int A[] = { 111, 2, 37, 3, 4, 100, 0, 600, 20, 10, -11};
61     int max, min;
62     MaxMin(A, 11, max, min);
63     cout << max << " " << min << endl;
64     return 0;
65 }

最多3*(n / 2)次比较

二.在最坏情况下 找到n个元素第二小

http://blog.csdn.net/mishifangxiangdefeng/article/details/7983809

三.线性选择算法

 1 #include<iostream>
 2 #include<stdlib.h>
 3 using namespace std;
 4
 5 template <typename T>
 6 int Partition(T A[], int p, int r)
 7 {
 8     T x = A[r];
 9     int i = p - 1;
10     for (int j = p; j <= r - 1; j++)
11     {
12         if (A[j] <= x)
13         {
14             i++;
15             T temp = A[j];
16             A[j] = A[i];
17             A[i] = temp;
18         }
19     }
20     T temp = A[i + 1];
21     A[i + 1] = A[r];
22     A[r] = temp;
23     return i + 1;
24 }
25
26 template <typename T>
27 int RandomizedPartition(T A[], int p, int r)
28 {
29     int i = rand() % (r - p + 1) + p;
30     T temp = A[r];
31     A[r] = A[i];
32     A[i] = temp;
33     return Partition(A, p, r);
34 }
35
36 template <typename T>
37 T RandomizedSelect(T A[], int p, int r, int i)
38 {
39     if (A != NULL && p >= 0 && r >= 0 && r >= p)
40     {
41         if (r - p + 1 < i)
42         {
43             return NULL;
44         }
45         else
46         {
47             if (r == p)
48             {
49                 return A[p];
50             }
51             int q = RandomizedPartition(A, p, r);
52             int k = q - p + 1;
53             if (i == k)
54             {
55                 return A[q];
56             }
57             else if (i < k)
58             {
59                 return RandomizedSelect(A, p, q - 1, i);
60             }
61             else
62             {
63                 return RandomizedSelect(A, q + 1, r, i - k);
64             }
65         }
66     }
67 }
68
69 int main()
70 {
71     double A[] = { 1.1, -2.1, 3, 3, 4, -10, 4, 2.6 ,20, 10};
72     cout << RandomizedSelect(A, 0, 9, 2) << endl; //-2.1
73     return 0;
74 }

四.最坏情况为线性的选择

1.将输入数组的n个元素划分为n/5组,每组5个元素,剩余的一组由n mod 5个元素组成

2.寻找n/5组,每组的中位数

3.对n/5个中位数用select找出其中位数x

4.用中位数x对输入的数进行划分

时间: 2024-10-04 23:44:18

顺序统计的相关文章

顺序统计:寻找序列中第k小的数

最直观的解法,排序之后取下标为k的值即可. 但是此处采取的方法为类似快速排序分块的方法,利用一个支点将序列分为两个子序列(支点左边的值小于支点的值,支点右边大于等于支点的值). 如果支点下标等于k,则支点就是查找的值,如果支点的下标大于k,则在左子序列里继续寻找,如果支点下标小于k,则继续在支点右子序列里面继续寻找第(k-支点下标)小的值. c#实现算法如下: public class FindSpecialOrderElement<T> where T : IComparable<T&

顺序统计树

/* * 顺序统计树 */ public class OrderStatisticTree { public static final OsTreeNode NIL = new OsTreeNode(RbColor.BLACK,0); private OsTreeNode root = null; public static void main(String[] args) { OrderStatisticTree ost = new OrderStatisticTree(); //测试插入 o

顺序统计:寻找序列中的最大最小数

查找输入序列中的最大最小数值,要求时间复杂度为1.5n C#实现如下: public class MinMaxFinder<T> where T : IComparable<T> { public void FindMinMax(T[] array, int startIndex, int endIndex, out T minValue, out T maxValue) { maxValue = array[startIndex]; minValue = array[startI

最大最小值以及前驱后继操作最坏情况都为O(1)的顺序统计树

问题:通过为结点增加指针的方式,试说明如何在扩张的顺序统计树上,支持每一动态集合查询操作MINIMUM,MAXIMUM,SUCCESSOR和PREDECESSOR在最坏时间O(1)内完成.顺序统计树上的其他操作的渐近性能不应受影响. 代码如下: //本程序在原有的红黑树基础上增加了子树结点个数,前驱后继结点以及最大小结点属性. #include <iostream> #include <time.h> using namespace std; #define BLACK 0 #de

《对寻找第i个顺序统计的数》一文的研究。

对于寻找第i个顺序统计的数,可以形式的定义如下: 对于这个问题,最原始的方法就是将1~n个数从小到大排序,然后输出第i个数.用快排的话,时间复杂度就是O(nlogn),但是我们其实可以对快速排序进行优化. 快速排序是以二分的思想,对分出的每边进行排序,然而当我们要求第i个数时,知道在快拍的哪一边的时候,我们还需对快排的另一边排序吗?毋庸置疑,这是不用的,所以这就是优化--只对快排的某一边进行处理. 设对A[L..R]进行划分.首先,按照快排的中心思想,选出(l+r) div 2这个元素作为"支点

算法导论--动态顺序统计与区间树

本文的基础是红黑树 算法导论–红黑树 通过在基础的数据结构中添加一些附加信息,来扩张一种标准的数据结构,然后编写新的操作来支持所需要的应用.下面是介绍在红黑树的基础上扩张的数据结构. 1.动态顺序统计 动态顺序统计可以在O(lgn)时间内确定任何的顺序统计量(即在n个元素的集合中,能在O(lgn)的时间内确定第i小的元素),同时也可以在O(lgn)的时间内计算一个元素的秩(即它在中序遍历下的位置顺序). 1 添加附加信息 结点x中加入x.size , size的大小为以x为根的子树(包含x本身)

算法导论-顺序统计

目录 1.问题的引出-求第i个顺序统计量 2.方法一:以期望线性时间做选择 3.方法二(改进):最坏情况线性时间的选择 4.完整测试代码(c++) 5.参考资料 内容 1.问题的引出-求第i个顺序统计量 什么是顺序统计量?及中位数概念 在一个由元素组成的集合里,第i个顺序统计量(order statistic)是该集合第i小的元素.例如,最小值是第1个顺序统计量(i=1),最大值是第n个顺序统计量(i=n).一个中位数(median)是它所在集合的“中点元素”.当n为奇数时,中位数是唯一的:当n

顺序统计中值

问题描述:无序找第k小的数? 1.解法一 先排好序,再找第k小个数:返回A[k-1]:此解法的时间复杂度为:O(nlogn): 2.解法二 情况一:k = 1 和 k = n 就是找数组的最小值和最大值: 情况二:找出中位数 3.找中位数(随机选择算法) 利用快速排序的原理,一轮排序,有2种情况: if i = k-1:返回a[i]: if i != k-1:左边/右边递归查找,时间复杂度为:O(n): 具体思想: 分析:在大多数情况下的时间复杂度是:O(n):但是最坏情况,完全顺序下找第k =

完整的C++实现算法导论十三章红黑树以及十四章中的顺序统计树

#include<iostream> using namespace std; class BRTree; class BRTreeNode{ private: friend class BRTree; int key; bool color; int size; BRTreeNode *left; BRTreeNode *right; BRTreeNode *parent; public: //创建一个默认构造函数 BRTreeNode():key(-1),color(0),size(0),

算法系列笔记2(静态表顺序统计-随机选择算法)

问题:当给定存在静态表(如数组)中的n个元素,如何快速找到其中位数.最小值.最大值.第i小的数? 首先想到的方法是先对数组元素进行排序,然后找到第i小的元素.这样是可行的,但比较排序最快也需要O(nlgn),能否在线性时间内解决呢.这就是随机的分治法-随机选择. 思想:利用随机划分(在快速排序中介绍过)找到主元r,这样就将小于等于r的元素放在了其左边,大于r的元素放在了其右边.这是可以计算出r的rank为k,如果正好等于i,则就返回该元素:如果k大于i,则在左边中寻找第i小的元素,否则在右边中寻