码迷,mamicode.com
首页 > 编程语言 > 详细

看数据结构写代码(67) 置换 _ 选择排序(完结篇)

时间:2015-05-06 11:10:18      阅读:160      评论:0      收藏:0      [点我收藏+]

标签:置换选择排序   外部排序   最佳归并树   

杂谈: 严蔚敏版《数据结构(C语言版)》 一书 终于看完了。这是 一个完结,也是 一个新的开端。《算法导论》 已到手。

置换选择排序的思想 是 将 归并段 尽量 变的 更大,而不是根据 内存 大小 限制在 固定的 大小。 这样 可以 利用赫夫曼树 来 进行 最优归并树,从而 使 外存 读写次数 最少。

下面给出 具体 代码:欢迎指出代码不足。

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

#include "stdafx.h"
#include <climits>
#define M 6//内存一次可容纳的 组数

typedef int LoseTree[M];
typedef struct RcdNode
{
	int key;
	int rNum;//归并段 的段号
}WorkArea[M+1];//内存工作区域。。。

//假设这些文件 存放在 硬盘中..
static int testArray[] = {10,15,169,3,209,18,20,20,22,40,6,15,25,12,37,48,99,100,INT_MAX};
static int readIndex = 0;//读到的索引位置
static int maxIndex = 18;

//调整 函数
void select_miniMax(LoseTree t,WorkArea wa,int i){
	int f = (i + M) / 2;
	while (f > 0){
		RcdNode n1 = wa[i];
		RcdNode n2 = wa[t[f]];
		if (n1.rNum > n2.rNum || (n1.rNum == n2.rNum && n1.key > n2.key) ){
			int temp = t[f];
			t[f] = i;
			i = temp;
		}
		f = f / 2;
	}
	t[0] = i;
}

void initTree(LoseTree t,WorkArea wa){
	for (int i = 0; i < M; i++){//初始化段号为0
		wa[i].rNum = t[i] = 0;
	}
	for (int i = M -1; i>= 0; i--){
		wa[i].key = testArray[readIndex++];
		wa[i].rNum = 1;
		select_miniMax(t,wa,i);
	}
}

void getRun(LoseTree t,WorkArea wa,int  rc,int *  rMax){//获得 归并段
	printf("-------------------------第%d段------------------------------\n",rc);
	while (wa[t[0]].rNum == rc){
		int q = t[0];
		int miniMax = wa[q].key;
		printf("%d\t",miniMax);
		//读入 下一个记录
		if (readIndex >= maxIndex){//到达记录的结尾
			wa[q].rNum = *rMax + 1;
			wa[q].key = INT_MAX;
			
		}
		else{
			int key = wa[q].key = testArray[readIndex++];
			if (key < miniMax){
				*rMax = rc + 1;
				wa[q].rNum = *rMax;;
			}
			else{
				wa[q].rNum = rc;
			}
		}
		select_miniMax(t,wa,q);
	}
	printf("\n");
}

void replace_Selection(){
	LoseTree t;
	WorkArea wa;
	initTree(t,wa);//初始化。。
	int rc =1, rmax = 1;
	while (rc <= rmax){
		getRun(t,wa,rc,&rmax);
		rc = wa[t[0]].rNum;
	}
}

int _tmain(int argc, _TCHAR* argv[])
{
	replace_Selection();
	return 0;
}

测试用例:static int testArray[] = {10,15,169,3,209,18,20,20,22,40,6,15,25,12,37,48,99,100,INT_MAX}

假设 这些数据存放在硬盘中,内存一次只能 读取 6组 数据。 之前的 分配方式,将 18 个数据 分成 3组。现在 分成 2组。一组 11 个,一组 7个。

技术分享

这样 我们可以 使用 2路 归并,一趟 归并 就行了,总的 外存 读写 次数 为 18。而 被 分成 3组的 方式 需要 2趟 归并,总的 外存读写次数为 36。

肯定 有人 要 说 用 3路 归并 不就 都是 一趟 归并了,总的 外存读写次数 为 18。可是 这样 会 导致 归并的 时间 增加。

看数据结构写代码(67) 置换 _ 选择排序(完结篇)

标签:置换选择排序   外部排序   最佳归并树   

原文地址:http://blog.csdn.net/fuming0210sc/article/details/45530261

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!