线性时间选择 5元组选中位数法
来源:互联网 发布:hexo 阿里云 编辑:程序博客网 时间:2024/06/06 05:32
///////////////////////////////////////////////////////////////////////////*// [8/7/2011] By Whisper对那些证明,O(X)我真的不太懂怎么证,数学学的不是太好。希望读到这篇代码的,懂的朋友可以留言帮助我理解一下,我只是简单的将代码实现了,需要的就来拿吧。在看这个选择算法的时候,应该对前面那个三位取中划分有些了解。其中有好多细节,我就不写了,代码能表述一切。http://blog.csdn.net/v_july_v/article/details/6431001 这里有一篇很不错的讲解。算法导论9.3节代码实现主要思想:1. 对输入的数组分成 N/5个5元组,最后一个元组个数为 n % 52. 对 N/5 个5元组,进行排序,找出其中的中位数(就是第3个数),再存成一个有N/5个数的中位数数组3. 再对这N/5个中位数, 递归查找中位数。4. 按找到的这个数,进行左右划分5. 如果要查找的第K大个数与这个划分点位置相等,则返回,如果小于,则在左边,否则在右边。*/////////////////////////////////////////////////////////////////////////////test.cpp VC6 编译通过//////////////////////////////////////////////////////////////////////////#include <iostream>#include <time.h>#include "initFuncs.h" //此文件包含了随机初始化函数 RndInitArray() 和 输出函数 Outprint()//下面是initFuncs.h的辅助函数代码,可以自己组织一下。 /*#ifndef _FUNC_INIT_#define _FUNC_INIT_ #include <STDLIB.H>#include <time.h>#include <stdio.h>#endif void RndINitArray(int nArray[], int nArraySize);void OutPrint(int nArrany[], int nArraySize); void RndINitArray(int nArray[], int nArraySize){srand(time(NULL));for (int i = 0; i < nArraySize; i++){nArray[i] = rand() % 90 + 10;}}void OutPrint(int nArray[], int nArraySize){ for (int i = 0; i < nArraySize; i++) { printf("%3d", nArray[i]); } printf("\n\n");}*/#define ARRAY_SIZE 12void Swap(int *x, int *y); //交换函数void InsertSort(int nArray[], int left, int right); //插入排序int RandomizedPartition(int a[], int left, int right); //分隔函数int RandomizedSelect(int a[], int left, int right, int k); //线性选择主函数int MidNum(int nArray[], int left, int right); //选取5元组的中位数的中位数const int nMidArraySize = ARRAY_SIZE / 5 + 1;int nMidArray[nMidArraySize];//------------------------测试-------------------------int main(void){int nArray[ARRAY_SIZE];RndINitArray(nArray, ARRAY_SIZE);printf("\n\tArray Size is %d\n\n", ARRAY_SIZE);printf("original Array:\n");OutPrint(nArray, ARRAY_SIZE);printf("RandomizedSelected from 1 to %d\n", ARRAY_SIZE); for (int i = 1; i <= ARRAY_SIZE; i++) { printf("%3d", RandomizedSelect(nArray, 0, ARRAY_SIZE, i)); }//printf("%d\n", RandomizedSelect(nArray, 0, ARRAY_SIZE, 5));printf("\n\n");printf("Compare with InsertSort:\n");InsertSort(nArray, 0, ARRAY_SIZE);OutPrint(nArray, ARRAY_SIZE);return 1;}//----------------------------插入---------------------------void InsertSort(int nArray[], int left, int right){for (int i = left + 1; right > 1; right--){int nTmpKey = nArray[i];int j = i++ - 1;while (j >= left && nArray[j] > nTmpKey){nArray[j + 1] = nArray[j];j--;}nArray[j + 1] = nTmpKey;}}void Swap(int *x, int *y) { int t = *x;*x = *y;*y = t;}int RandomizedPartition(int a[], int left, int right) {//寻找中位数 int x = MidNum(a, left, right);int index = left;while(x != a[index++]); //寻找中位数在数组中的位置index--; //也可以从新设计存储结构Swap(&a[index], &a[left]); int i = left, j = right; while (true) {while (a[++i] < x);while (a[--j] > x);if (i >= j){break;}Swap(&a[i], &a[j]); }Swap(&a[j], &a[left]); return j; //返回Select位置}//--------------------------利用快排思想,一半一半的找--------------int RandomizedSelect(int a[], int left, int right, int k){ int i = RandomizedPartition(a, left, right), j = i - left+1;if (j == k) //终结状态 { return a[i]; } else if (k < j) { return RandomizedSelect(a, left, i, k); //在左边 } else { return RandomizedSelect(a, i+1, right, k-j); //在右边 }}//-------------------------选取5元组的中位数----------------------------int MidNum(int nArray[], int left, int right){if (1 == right) //直到最后只剩一个元素,即是中位数的中位数{return nArray[left];}int remainder = (right - left) % 5;int i = left, j = 0;for (; i < right - remainder; i += 5){InsertSort(nArray, i, 5); //对每个5元组进行插入排序nMidArray[j++] = nArray[i + 2]; //存放中位数}//如果存在剩余元素则处理剩余元素if (remainder > 0){InsertSort(nArray, i, remainder);nMidArray[j++] = nArray[i + remainder / 2]; }//从中位数组中寻找中位数int nMidElem = (right - left) / 5 + (0 != remainder); return MidNum(nMidArray, 0, nMidElem);}
下面是测试结果:
- 线性时间选择 5元组选中位数法
- 分治法--线性时间选择
- 【分治法】线性时间选择算法
- 线性时间选择【递归分治法】
- 线性时间选择
- 线性时间选择
- 线性时间选择
- 期望线性时间选择
- 线性时间选择
- 线性时间选择
- 线性时间选择
- 线性时间选择
- 线性时间选择
- 线性时间选择
- 线性时间选择
- 线性时间选择
- 线性时间选择
- 线性时间选择算法
- Linux makefile 教程 非常详细,且易懂
- 创建型--抽象工厂
- 走向绝境的现代社会
- zoj 1657 hash、、、
- 中文乱码问题及其解决方法
- 线性时间选择 5元组选中位数法
- SL400插上电源适配器后就断网的问题处理
- 一个Udp通信的小程序
- ubuntu环境下编译内核step by step
- 如何通过maven创建基于eclipse的web应用
- 最近在建模,顺便汉化一个软件玩玩
- MyGUI3.0.1支持中文输入
- scanf中的%[^]%*c格式
- AfxMessageBox弹出的对话框时,关闭父窗口的父窗口引起的问题。