算法导论-------------中位数和顺序统计学

文章来自网络加课本:

本次学习的内容讨论的问题是在一个由n个不同数值构成的集合中选择第i个顺序统计量问题。主要讲的内容是如何在线性时间内O(n)时间内在集合S中选择第i小的元素,最基本的是选择集合的最大值和最小值。一般情况下选择的元素是随机的,最大值和最小值是特殊情况,书中重点介绍了如何采用分治算法来实现选择第i小的元素,并借助中位数进行优化处理,保证最坏保证运行时间是线性的O(n)。

1、基本概念

  顺序统计量:在一个由n个元素组成的集合中,第i个顺序统计量是值该集合中第i小的元素。例如最小值是第1个顺序统计量,最大值是第n个顺序统计量。

中位数:一般来说,中位数是指它所在集合的“中间元素”,当n为奇数时,中位数是唯一的,出现位置为n/2;当n为偶数时候,存在两个中位数,位置分别为n/2(上中位数)和n/2+1(下中位数)。

2、选择问题描述

  输入:一个包含n个(不同的)数的集合A和一个数i,1≤i≤n。

输出:元素x∈A,它恰大于A中其他的i-1个元素。

最直接的办法就是采用一种排序算法先对集合A进行排序,然后输出第i个元素即可。可以采用前面讲到的归并排序、堆排序和快速排序,运行时间为O(nlgn)。接下来书中由浅入深的讲如何在线性时间内解决这个问题。

3、最大值和最小值

  要在集合中选择最大值和最小值,可以通过两两元素比较,并记录最大值和最小值,n元素的集合需要比较n-1次,这样运行时间为O(n)。举个例子来说明,现在要求和集合A={32,12,23,67,45,78}的最大值,开始假设第一个元素最大,即max=1,然后从第二个元素开始向后比较,记录最大值的位置。执行过程如下图所示:

书中给出的求最小值的伪代码如下:

1 MINMUN(A)
2    min = A[1]
3    for i=1 to length(A)
4       do if min > A[i]
5                then  min >= A[i]
6   return min

问题:

(1)同时找出集合的最大值和最小值

方法1:按照上面讲到的方法,分别独立的找出集合的最大值和最小值,各用n-1次比较,共有2n-2次比较。

方法2:可否将最大值和最小值结合在一起寻找呢?答案是可以的,在两两比较过程中同时记录最大值和最小值,这样最大需要3n/2次比较。现在的做法不是将每一个      输入元素与当前的最大值和最小值进行比较,而是成对的处理元素,先将一对输入元素进行比较,然后把较大者与当前最大值比较,较小者与当前最小者比较,因此每两个元素需要3次比较。初始设置最大值和最小值方法:如何n为奇数,就将最大值和最小值都设置为第一个元素的值,然后成对的处理后续的元素。如果n为偶数,那么先比较前面两个元素的值,较大的设置为最大值,较小的设置为最小值,然后成对处理后续的元素。这样做的目的保证能够成对的处理后续的元素。举个例子说明这个过程,假设现在要找出集合A={32,23,12,67,45,78,10,39,9,58}最大值和最小值,执行过程如下:

#include<iostream>
using namespace std;

void get_max_min(int a[],int len, int *max, int *min)
{
	int tmp_max, tmp_min;

	if (len % 2 == 0)
	{
		if (a[0] > a[1])
		{
			*max = a[0];
			*min = a[1];
		}
		else{
			*max = a[1];
			*min= a[0];
		}

		for (int i = 2; i < len; i = i + 2)
		{
			if (a[i]>a[i + 1])
			{
				tmp_max = a[i];
				tmp_min = a[i + 1];
			}
			else
			{
				tmp_max = a[i + 1];
				tmp_min = a[i];
			}

			if (*max < tmp_max)
				*max = tmp_max;
			if (*min>tmp_min)
				*min = tmp_min;
		}
	}
	else
	{
		*max = a[0];
		*min = a[0];

		for (int i = 1; i < len; i = i + 2)
		{
			if (a[i]>a[i + 1])
			{
				tmp_max = a[i];
				tmp_min = a[i + 1];
			}
			else
			{
				tmp_max = a[i + 1];
				tmp_min = a[i];
			}

			if (*max < tmp_max)
				*max = tmp_max;

			if (*min>tmp_min)
				*min = tmp_min;
		}
	}
}

int main()
{

	int a[] = { 23, 12, 34, 26, 78, 45, 87, 15, 60, 19, 11 };
	int len = sizeof(a) / sizeof(int);

	cout << len << endl;

	int max_value, min_value;
	get_max_min(a, len, &max_value, &min_value);

	cout << max_value << endl;
	cout << min_value << endl;

	return 0;
}

时间: 2024-12-16 07:44:11

算法导论-------------中位数和顺序统计学的相关文章

算法导论 第9章 中位数和顺序统计学

/* * 算法导论 第九章 中位数和顺序统计学 * 线性时间选择元素 */ #include <iostream> #include <ctime> using namespace std; int minimum(int *arr, int len); int randomizedSelect(int *arr, int p, int r, int i); int randomizedPartition(int *arr, int p, int r); void exchange

算法导论第9章中位数和顺序统计学

#include <iostream> #include <stdint.h> #ifdef __linux #include <stdio.h> #endif // MINIMUM(A) // MIN = A[1] // for i = 2 to A.length // if min > A[i] // min = A[i] // return min int64_t minimum(int64_t* A, int64_t n) { int64_t min =

算法导论(第9章-中位数和顺序统计学)最大值和最小值

n个数中同时找出最大值跟最小值: 例子:n = 7 5  1  2  3  6  4  8 方法一:独立地找出最大值和最小值,各用n-1次比较,共有2n-2次比较. 方法二:成对地处理元素,先将一对输入元素相互比较,然后把较小者与当前最小值比较,把较大者与当前最大值比较,因此每两个元素需要比较3次.(n为奇数时,将最大值和最小值都设为第一个元素的值,然后成对地处理余下的元素,总共做了3*[n/2]次比较,[]为下界.n为偶数时,就对前两个元素做一次比较,以决定最大值和最小值的初始值,然后成对地处

算法导论 中位数和顺序统计量(python)

第i个顺序统计量:该集合中第i小的元素(建集合排序后第i位 当然算法可以不排序) 中位数:集合中的中点元素 下中位数 上中位数 9.1最大值和最小值 单独的max或min每个都要扫一遍 n-1次比较 如果同时找max和min 要 :1.2个数相互比较 1次{每次选出2个 选n//2次} 2.大的和max比较 3.小的和min比较 找出序列为第i小的数Θ(n) 随机快速排序的运用:(可以回去看快排) 代码: import random def PARTTION(A,p,r): x = A[r] i

算法导论—中位数与顺序统计量

一.选择最大值或者最小值的最优算法 对于长度为n的数组,已证找最大值或者最小值比较操作下界就是n-1.所以只需要让第一个值为初始最大值或者初始最小值,用所有的值与这个值比较,更新这个值即可. def minimum(a): minNum=a[0] for i in range(1,len(a)): if minNum>a[i]: minNum=a[i] return minNum print(minimum ([1,2,3,4,5,6,7,8,9])) 二.同时选择最大值和最小值的快速算法(成对

(转)算法导论—中位数与顺序统计量

http://m.blog.csdn.net/blog/zhangzhengyi03539 http://m.blog.csdn.net/blog/zhangzhengyi03539/46795831 一.选择最大值或者最小值的最优算法 对于长度为n的数组,已证找最大值或者最小值比较操作下界就是n-1.所以只需要让第一个值为初始最大值或者初始最小值,用所有的值与这个值比较,更新这个值即可. def minimum(a): minNum=a[0] for i in range(1,len(a)):

算法导论-中位数和顺序统计量

在一个由n个元素组成的集合中,第i个顺序统计量是该集合中第i小的元素.一个中位数是它所属集合的“中点元素”.当n为奇数时,中位数是唯一的,位于i=(n+1)/2处:当n为偶数时,存在两个中位数,分别位于i=n/2和i=n/2+1处.如果不考虑n的奇偶性,中位数总是出现在i=⌊(n+1)/2⌋处(下中位数)和i=⌈(n+2)/2⌉(上中位数). 1.最小值和最大值 在一个有n个元素的集合中,需要做n-1次(上界)比较才能找到最小值或最大值. int MiniValue(const int *A,

算法导论CLRS答案

目前正在编写算法导论答案,欢迎大家follow me at mygithub 刚完成第9章,中位数和顺序统计学 正在编写第13章,红黑树 想要参与的朋友可以告诉我想要编写的章节,开个branch给你------

算法导论 学习资源

学习的过程会遇到些问题,发现了一些比较好的资源,每章都会看下别人写的总结,自己太懒了,先记录下别人写的吧,呵呵. 1  Tanky Woo的,每次差不多都看他的 <算法导论>学习总结 - 1.前言 <算法导论>学习总结 - 2.第一章 && 第二章 && 第三章 <算法导论>学习总结 - 3.第四章 && 第五章 <算法导论>学习总结 - 4.第六章(1) 堆排序 <算法导论>学习总结 - 5.第六