算法导论第九章-中位数和顺序统计量-Cpp代码实现

根据书上内容实现了最大值,最小值,第i小的数,第i大的数和求数组的中位数。


statistic_tool.h

#pragma once

/*************************************************
Author:董小歪
Date:2016-06-07
Description:算法导论第九章-中位数和顺序统计量-Cpp代码实现
**************************************************/

//为了实现算法导论中的下标从1开始,在data下标为0的元素添加一个“哨兵”元素0

#pragma once

#ifndef STATISTIC_TOOL_H
#define STATISTIC_TOOL_H
using namespace std;

#include <iostream>
#include <vector>
#include <random>
#include <time.h>

class Statistic_Tool {
public:
	template<typename T> T minimum(const vector<T> &vec);		//最小值
	template<typename T> T maximum(const vector<T> &vec);		//最大值
	template<typename T> T randomized_select(vector<T> &vec, int l, int r, int index);		//返回数据中第i小的值
	template<typename T> T randomized_select2(vector<T> &vec, int l, int r, int index);		//返回数据中第i大的值
	template<typename T> double fild_median(vector<T> &vec);			//返回数据中的中位数

private:
	template<typename T> unsigned randomized_partition(vector<T> &vec, int l, int r);   //随机划分
};

template<typename T>
T Statistic_Tool::minimum(const vector<T> &vec)
{
	if (vec.empty())
		return INT_MIN;
	T ret = vec[0];
	for (int i = 1; i < vec.size(); ++i)
		if (vec[i] < ret)
			ret = vec[i];
	return ret;
}

template<typename T>
T Statistic_Tool::maximum(const vector<T> &vec)
{
	if (vec.empty())
		return INT_MAX;
	T ret = vec[0];
	for (int i = 1; i < vec.size(); ++i)
		if (vec[i] > ret)
			ret = vec[i];
	return ret;
}

template<typename T>
T Statistic_Tool::randomized_select(vector<T> &vec, int l, int r, int index)
{
	if (l == r)
		return vec[l];
	int q = randomized_partition(vec, l, r);
	int k = q - l + 1;
	if (index == k)
		return vec[q];
	else if (k < index)
		return randomized_select(vec, q + 1, r, index - k);
	else
		return randomized_select(vec, l, q - 1, index);
}

template<typename T>
T Statistic_Tool::randomized_select2(vector<T> &vec, int l, int r, int index)
{
	if (l == r)
		return vec[l];
	int q = randomized_partition(vec, l, r);
	int k = r - q + 1;
	if (index == k)
		return vec[q];
	else if (k < index)
		return randomized_select2(vec, l, q - 1, index - k);
	else
		return randomized_select2(vec, q + 1, r, index);
}

template<typename T>
unsigned Statistic_Tool::randomized_partition(vector<T> &vec, int l, int r)
{
	uniform_int_distribution<unsigned> u(l, r);
	default_random_engine e;
	int random = u(e);
	swap(vec[random], vec[r]);
	int x = vec[r];
	int i = l - 1;
	for (int j = l; j < r; ++j)
	{
		if (vec[j] < x)
		{
			++i;
			swap(vec[i], vec[j]);
		}
	}
	swap(vec[r], vec[i + 1]);
	return i + 1;
}

template<typename T>
double Statistic_Tool::fild_median(vector<T> &vec)
{
	if (vec.size() & 0x00000001)
		return randomized_select(vec, 0, vec.size() - 1, vec.size() / 2 + 1);
	else
		return static_cast<double>(randomized_select(vec, 0, vec.size() - 1, vec.size() / 2) + randomized_select(vec, 0, vec.size() - 1, vec.size() / 2 + 1)) / 2;
}

#endif // !STATISTIC_TOOL_H

测试用例:

#include "statistic_tool.h"

int main()
{
	Statistic_Tool st;
	vector<int> data = { 12,1,4,40,29,18,3,9 };
	cout << "原数据是:";
	for (auto e : data)
		cout << e << " ";
	cout << endl << endl;
	cout << "最小值是:" << st.minimum(data) << endl << endl;
	cout << "最大值是:" << st.maximum(data) << endl << endl;

	vector<int> copy = data;
	uniform_int_distribution<unsigned> u(1, copy.size());
	default_random_engine e(time(0));
	int index = u(e);

	cout << "第" << index << "小的数字是:" << st.randomized_select(copy, 0, copy.size() - 1, index) << endl << endl;
	cout << "第" << index << "大的数字是:" << st.randomized_select2(copy, 0, copy.size() - 1, index) << endl << endl;

	cout << "数据:";
	for (auto e : data)
		cout << e << " ";
	cout << "的中位数是:" << st.fild_median(data) << endl << endl;

	vector<int> data2 = { 1,4,40,29,18,3,9 };
	cout << "数据:";
	for (auto e : data2)
		cout << e << " ";
	cout << "的中位数是:" << st.fild_median(data2) << endl << endl;


	system("pause");
}

测试结果截图:


  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值