【编程练习】快速select算法的实现

 

 代码来自:

 

http://blog.csdn.net/v_JULY_v

 

 

算法思想:

 

// Quick_select.cpp : 定义控制台应用程序的入口点。
//

#include "stdafx.h"
#include <iostream>
#include <time.h>

using namespace std;

const int num_array = 13;
const int num_med_array = num_array/5 + 1;

int array[num_array];
int midian_array[num_med_array];

/*
//插入排序算法伪代码
INSERTION-SORT(A)                                                 cost times
1 for j ← 2 to length[A]                                           c1 n
2 do key ← A[j]                                                    c2 n - 1
3 Insert A[j] into the sorted sequence A[1 ‥ j - 1]. 0...n - 1
4 i ← j - 1                                                        c4 n - 1
5 while i > 0 and A[i] > key                                        c5
6 do A[i + 1] ← A[i]                                               c6
7 i ← i - 1                                                        c7
8 A[i + 1] ← key                                                   c8 n - 1
*/

void insert_sort(int array[], int left, int loop_times)
{//这块的插入排序感觉有点问题,第一个数字没有排啊
	for (int j = left; j < left+loop_times; j++)
	{
		int key = array[j];
		int i = j - 1;

		while (i > left && array[i] > key)
		{
			array[i+1] = array[i];
			i--;
		}

		array[i+1] = key;
	}
}

void insertion_sort(int array[],int first,int last)
{
	int i,j;
	int temp;
	for(i = first + 1 ;i<=last;i++)
	{
		temp = array[i];
		j=i-1;
		//与已排序的数逐一比较,大于temp时,该数移后
		while((j>=0)&&(array[j]>temp))
		{
			array[j+1]=array[j];
			j--;
		}
		//存在大于temp的数
		if(j!=i-1)
		{array[j+1]=temp;}
	}

}

int find_median(int array[], int left, int right)
{
	if (left == right)
		return array[left];int index;
	for (index = left; index < right - 5; index += 5)
	{
		//insert_sort(array, index, 4);
		insertion_sort(array,index,4);
		int num = index - left;
		midian_array[num / 5] = array[index + 2];
	}
	// 处理剩余元素
	int remain_num = right - index + 1;
	if (remain_num > 0)
	{
		//insert_sort(array, index, remain_num - 1);
		insertion_sort(array,index,remain_num - 1);
		int num = index - left;
		midian_array[num / 5] = array[index + remain_num / 2];
	}
	int elem_aux_array = (right - left) / 5 - 1;
	if ((right - left) % 5 != 0)
		elem_aux_array++;
	// 如果剩余一个元素返回,否则继续递归
	if (elem_aux_array == 0)
		return midian_array[0];
	else
		return find_median(midian_array, 0, elem_aux_array);
}

// 寻找中位数的所在位置
int find_index(int array[], int left, int right, int median)
{
	for (int i = left; i <= right; i++)
	{
		if (array[i] == median)
			return i;
	}
	return -1;
}

int q_select(int array[], int left, int right, int k)
{
	// 寻找中位数的中位数
	int median = find_median(array, left, right);
	// 将中位数的中位数与最右元素交换
	int index = find_index(array, left, right, median);
	swap(array[index], array[right]);
	int pivot = array[right];
	// 申请两个移动指针并初始化
	int i = left;
	int j = right - 1;
	// 根据枢纽元素的值对数组进行一次划分
	while (true)
	{
		while(array[i] < pivot)
			i++;
		while(array[j] > pivot)
			j--;
		if (i < j)
			swap(array[i], array[j]);
		else
			break;
	}
	swap(array[i], array[right]);
	/* 对三种情况进行处理:(m = i - left + 1)
	1、如果m=k,即返回的主元即为我们要找的第k 小的元素,那么直接返回主元a[i]即可;
	2、如果m>k,那么接下来要到低区间A[0....m-1]中寻找,丢掉高区间;
	3、如果m<k,那么接下来要到高区间A[m+1...n-1]中寻找,丢掉低区间。
	*/
	int m = i - left + 1;
	if (m == k)
		return array[i];
	else if(m > k)
		//上条语句相当于if( (i-left+1) >k),即if( (i-left) > k-1 ),于此就与2.2 节里的
		//代码实现一、二相对应起来了。
		return q_select(array, left, i - 1, k);
	else
		return q_select(array, i + 1, right, k - m);
}

int _tmain(int argc, _TCHAR* argv[])
{
	//srand(unsigned(time(NULL)));
	//for (int j = 0; j < num_array; j++)
	int a[4] = {13,26,9,100};
	insert_sort(a,0,3);

	//insertion_sort(a,0,3);

	cout<<a[0]<<a[1]<<a[2]<<a[3]<<endl;

	//array[j] = rand();
	int array[num_array]={0,45,78,55,47,4,1,2,7,8,96,36,45};
	// 寻找第k 最小数
	int k = 13;
	int i = q_select(array, 0, num_array - 1, k);
	cout << i << endl;

	getchar();
	return 0;
}

 

时间: 2024-09-20 14:36:41

【编程练习】快速select算法的实现的相关文章

c++-C++计算哈密尔顿回路的优化算法的实现?请各位高手都来帮帮忙吧

问题描述 C++计算哈密尔顿回路的优化算法的实现?请各位高手都来帮帮忙吧 C++计算哈密尔顿回路的优化算法的实现?请各位高手都来帮帮忙吧 解决方案 http://wenku.baidu.com/link?url=Aue42qZXYxiqlYt5WJJ-rMyFkotcIy501YzLF2V1Eww1j17n7myWEj0Z7bNIPYZcqsmlBf9UMqfGRmn5Z6E3iHliGQaJPCLBnpG7pilNmVm

粒子群算法(5)-----标准粒子群算法的实现

标准粒子群算法的实现思想基本按照粒子群算法(2)----标准的粒子群算法的讲述实现.主要分为3个函数.第一个函数为粒子群初始化函数 InitSwarm(SwarmSize......AdaptFunc)其主要作用是初始化粒子群的粒子,并设定粒子的速度.位置在一定的范围内.本函数所采用的数据结构如下所示: 表ParSwarm记录的是粒子的位置.速度与当前的适应度值,我们用W来表示位置,用V来代表速度,用F来代表当前的适应度值.在这里我们假设粒子个数为N,每个粒子的维数为D. W1,1 W1,2 .

C++火车入轨算法的实现代码

 这篇文章主要介绍了C++火车入轨算法的实现代码,有需要的朋友可以参考一下 [问题描述]   某城市有一个火车站,铁轨铺设如图所示.有n节车厢从A方向驶入车站,按进站顺序编号为1~n.你的任务是让它们按照某种特定的顺序进入B方向的铁轨并驶出车站.为了重组车厢,你可以借助中转站C.这是一个可以停放任意多节车厢的车站,但由于末端封顶,驶入C的车厢必须按照相反的顺序驶出.对于每个车厢,一旦从A移入C,就不能再回到A了:一旦从C移入B,就不能回到C了.换句话说,在任意时刻,只有两种选择:A→C和C→B.

大神帮看一下这个算法的实现思路?

问题描述 大神帮看一下这个算法的实现思路? 字符串 = "a/b/c_d/e/f_m/n/k_o/p": 字符串的长度是不确定的,通过组合把字符串 拆分成a/d/m/o, a/d/m/p,a/d/n/o,... 依次这样组合. 解决方案 参考:http://bbs.csdn.net/topics/390951529 解决方案二: 非常感谢 ,算法不错

关于分页算法的实现 求助

问题描述 关于分页算法的实现 求助 1 2 3 ...6 下一页 这种分页算法是什么 小弟实在不会 求各位大神帮忙解答下 解决方案 这种分页插件,网上很多. 解决方案二: 可以用jquery自带的分页,只要设置几个属性,其他的都不用管

排序算法的实现及性能分析

排序算法的实现及性能分析 --(java版) 排序是对数据元素序列建立某种有序排列的过程.更确切的说,排序是把一个数据元素序列整理成按关键字递增(或递减)排列的过程. 不过首先,我们必须先解释一下关键字这个词.关键字是要排序的数据元素集合中的一个域,排序是以关键字为基准进行的.而关键字也分为主关键字和次关键字.对于要排序的数据元素集合来说,如果关键字满足数据元素值不同时,该关键字也不同,这样的关键字称为主关键字.不满足主关键字定义的就称为次关键字. 简单来说,排序分为内部排序和外部排序两种.内部

c-循环冗余校验(CRC)算法的实现

问题描述 循环冗余校验(CRC)算法的实现 循环冗余校验(CRC)算法的实现 1.设计要求 (1)利用结构体或数组模拟网络数据包结构. (2)编码实现CRC算法,并将得到的校验位附加到网络数据包相应的位置. (3)根据数据包的长度,随机生成一个数据包产生突变的位置,并对该位置的bit位模拟突变的产生. (4)重新利用CRC算法校验该数据包,并指出产生的结果. (5)CRC能够检出所有的错误吗?如果不能,你能构造出无法检错的实例吗? 2.课程设计报告内容 (1) 给出程序的流程图: (2) 给出程

数据结构-图的最短路径算法的实现

问题描述 图的最短路径算法的实现 设计内容: 设计校园平面图,所含景点不少于8个.以图中顶点表示学校内各景点,存放景点的名称.景点介绍信息等:以边表示路径,存放路径长度信息.要求将这些信息保存在文件graph.txt中,系统执行时所处理的数据要对此文件分别进行读写操作. 1.从文件graph.txt中读取相应数据, 创建一个图,使用邻接矩阵表示图 : 2.景点信息查询:为来访客人提供校园任意景点相关信息的介绍: 3.问路查询:为来访客人提供校园任意两个景点之间的一条最短路径 . 选做内容(对文件

VC++运功补偿算法的实现

问题描述 VC++运功补偿算法的实现 本人正在研究运动补偿算法,其中的钻石算法和六边形算法的实现,代码的实现有点点困难的,希望各位大神给点意见的.根本就不知道如何下手的,能给点点方向或者是要学习努力的东西吗?