Chinaunix首页 | 论坛 | 博客
  • 博客访问: 200823
  • 博文数量: 8
  • 博客积分: 221
  • 博客等级: 入伍新兵
  • 技术积分: 98
  • 用 户 组: 普通用户
  • 注册时间: 2010-03-07 20:40
文章分类

全部博文(8)

文章存档

2014年(1)

2012年(7)

我的朋友

分类: IT业界

2012-07-30 11:42:13

tags: 算法 多路归并


程序员编程艺术:第十章、如何给10^7个数据量的磁盘文件排序
关于多路归并排序 外部排序 败者树 




多路归并算法:

多路归并是外部排序(External Sort)的基础,实现也比较简单,和最简单的归并排序中的二路归并是基本一样的,只不过路数是浮动的k。

(1)假设有K路数据流,流内部是有序的,且流间同为升序或降序

(2)首先读取每个流的第一个数,如果已经EOF,pass

(3)将有效的k(k可能小于K)个数比较,选出最小的那路mink,输出,读取mink的下一个

(4)直到所有K路都EOF

代码如下:

001/*
002 * main.c
003 *
004 *  Created on: 2011-11-11
005 *      Author: liheyuan
006 */
007 
008#include
009#include
010#include
011 
012typedef int TYPE;
013 
014#define MIN_MAX 8888
015 
016void k_merge(TYPE** arrs, int* lens, int k)
017{
018    int* cnts = (int*) malloc(sizeof(int) * k);
019    int* has_next = (int*) malloc(sizeof(int) * k);
020    TYPE* datas = (int*) malloc(sizeof(int) * k);
021    int i;
022    int min_index = 0;
023    TYPE min;
024 
025    //Read each k-way first into data
026    for (i = 0; i < k; i++)
027    {
028        if (lens[i] >= 1)
029        {
030            datas[i] = arrs[i][0];
031            cnts[i] = 1;
032            has_next[i] = 1;
033        }
034        else
035        {
036            has_next[i] = 0;
037        }
038    }
039 
040    while (1)
041    {
042 
043        //Select min in k
044        min = MIN_MAX;
045        min_index = 0;
046        for (i = 0; i < k; i++)
047        {
048            if (has_next[i])
049            {
050                if (datas[i] < min)
051                {
052                    min = datas[i];
053                    min_index = i;
054                }
055            }
056        }
057 
058        if (min == MIN_MAX)
059        {
060            //No way has data
061            break;
062        }
063        else
064        {
065            //print
066            printf("%d\n", datas[min_index]);
067 
068            //Succ get one min
069            if (cnts[min_index] < lens[min_index])
070            {
071                datas[min_index] = arrs[min_index][cnts[min_index]];
072                cnts[min_index]++;
073            }
074            else
075            {
076                has_next[min_index] = 0;
077            }
078        }
079    }
080 
081    free(cnts);
082}
083 
084//void k_merge(TYPE** arrs, int* lens, int k)
085 
086int main()
087{
088    TYPE a[5] =
089    { 1, 3, 5, 7, 17 };
090    TYPE b[3] =
091    { -1, 10, 20 };
092    TYPE c[4] =
093    { -20, 30, 88, 111 };
094    TYPE* arrs[3] =
095    { a, b, c };
096    int lens[3] =
097    { 5, 3, 4 };
098 
099    k_merge(arrs, lens, 3);
100 
101    return 0;
102}

输出:

01-20
02-1
031
043
055
067
0710
0817
0920
1030
1188
12111





--EOF0--
阅读(9015) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~