zoukankan      html  css  js  c++  java
  • sicilyK路归并

      1 /*
    2 K路归并排序 ,
    3 主要思想 :
    4 建立K路链表 , 在K路的最小元素提取出来 。
    5 存储到 result数组中 , 利用result数组构造最小堆 ,
    6 每次取出堆顶的元素 , 在把取出的元素的那路的next填充到堆顶中, 重新维持堆特性
    7 通过每次取出堆顶 ,知道K路链表均被取完 ,完成归并排序
    8 */
    9 #include <stdio.h>
    10 #include <algorithm>
    11 #include <memory.h>
    12
    13 using namespace std;
    14 //定义链表节点
    15 struct node
    16 {
    17 int data ; //数据
    18 node *next;
    19 node()
    20 {
    21 next = NULL;
    22 }
    23 node( int x )
    24 {
    25 data = x ;
    26 next = NULL;
    27 }
    28 bool operator<(const node& temp)
    29 {
    30 if(data < temp.data)
    31 return true;
    32 return false;
    33 }
    34 };
    35 //定义链表,对于每路定义一个链表,用链表数组lists【101】表示
    36 struct list
    37 {
    38 node *root;
    39 node *pre ;
    40 list()
    41 {
    42 root = NULL;
    43 }
    44 //链表的插入操作
    45 void insert( int d )
    46 {
    47 node* node_temp = new node(d);
    48 if(root == NULL)
    49
    50 {
    51 root = node_temp;
    52 pre = root ;
    53 }
    54 else {
    55
    56 pre->next = node_temp;
    57 pre = node_temp;
    58 }
    59 }
    60 }lists[105];
    61
    62
    63
    64 int k , n , t ; // k表示归并的路数 , n表示每路所含的数字个数 , t为测试用例个数
    65 //定义构造堆的数组result
    66 node* result = new node[105];
    67 bool cmp( node a , node b)
    68 {
    69 return ( a.data > b.data );
    70 }
    71 //保持堆特性函数,非递归写法
    72 void min_heapify(node* &a, int i, int length)
    73 {
    74 int smallest = i;
    75 while(smallest <= length - 1)
    76 {
    77 int left = 2*smallest + 1;
    78 int right = 2*smallest + 2;
    79 int temp = smallest;
    80 if(left <= length - 1 && a[left] < a[smallest])
    81 {
    82 smallest = left;
    83 }
    84 if(right <= length - 1 && a[right] < a[smallest])
    85 {
    86 smallest = right;
    87 }
    88 //最小的元素位置错误 , 交换其位置 , 使其正确
    89 if(smallest != temp)
    90 {
    91 node exchange = a[smallest];
    92 a[smallest] = a[temp];
    93 a[temp] = exchange;
    94 }
    95 else
    96 break;
    97 }
    98 }
    99
    100 //归并主要函数
    101 void merge()
    102 {
    103 //首先建堆
    104 make_heap( result , result + k , cmp );
    105
    106 while ( k > 0 )
    107 {
    108 //输出堆顶元素
    109 printf("%d " , result[0].data );
    110 //判断当前堆顶元素是否存在后续
    111 if ( result[0].next != NULL )
    112 {
    113 //若存在 , 等于后续
    114 result[0] = *(result[0].next);
    115
    116 }
    117 else
    118 {
    119 //若不存在 , 说明该路已完成归并 ,K-- , 并且 将堆的最后一个值赋给堆顶 ,减小堆的节点个数
    120 result[0] = result[--k];
    121
    122 }
    123 //保持堆特性
    124 min_heapify(result, 0 , k) ;
    125 }
    126 printf("\n");
    127 }
    128 int main()
    129 {
    130 int tep;
    131 scanf( "%d" , &t );
    132 while ( t -- )
    133 {
    134 scanf("%d%d" , &k , &n ) ;
    135 memset( lists , 0 , sizeof( lists ));
    136 for ( int i = 0 ; i < k ; i ++)
    137
    138 for ( int j = 0 ; j < n ; j++)
    139 {
    140 scanf("%d" , &tep);
    141 lists[i].insert(tep);
    142 }
    143
    144 //构造数组result
    145 for ( int i = 0 ; i < k ; i ++)
    146 {
    147
    148 result[i] =* ( lists[i].root );
    149 }
    150 merge();
    151
    152 }
    153 return 0 ;
    154 }
  • 相关阅读:
    如何把项目上传到github
    springBoot整合Mybatis为什么可以省略mybatis-config.xml
    【Mybatis源码解析】-mybatis-spring原理解析
    没有名字 [整除分块优化dp]
    替身使者 [区间dp]
    P3158 [CQOI2011]放棋子 [动态规划]
    博士之时 [分类讨论, 计数]
    曾有两次 [最短路树]
    序列 [线段树]
    城镇 [树的直径, 启发式合并]
  • 原文地址:https://www.cnblogs.com/lzhenf/p/2288539.html
Copyright © 2011-2022 走看看