算法复习——堆排

Long long ago,我曾经想过要写堆排(话说已经是刚开始写二分那个博客的时候了),后来好久没写,现在总算想到要写了……

好了,进入正题。

我以前曾经自己打过一个课件,现在打算放在CSDN下载那里,就当是放基础知识了,现在写写一道题的题解……

PPT网址如下(下载者先交1积分……):http://download.csdn.net/detail/u014120397/9472391

题目:codevs1245

链接:http://codevs.cn/problem/1245/

K路归并,初始化的时候把a,b数组排个序,然后把a[1]+b[1],a[2]+b[1]……a[n]+b[1]放入小根堆里面,然后每出一次堆,比如说把a[i]+b[1]出堆了,那么就把a[i]+b[2]入堆,如此操作执行n次就可以了。时间复杂度O(n log n)

代码:

type arr=array[1..100000]of longint;
     ijk=record
     sum,b:longint;
     end;
var heap:array[0..1000000]of ijk;
    buf:ijk;
    a,b:arr;
    n,i,length:longint;
procedure qs(l,r:longint;var a:arr);
var i,j:longint;
    x,y:longint;
begin
  i:=l;
  j:=r;
  x:=a[(l+r) shr 1];
  repeat
    while a[i]<x do
    inc(i);
    while a[j]>x do
    dec(j);
    if i<=j then
    begin
      y:=a[i];
      a[i]:=a[j];
      a[j]:=y;
      inc(i);
      dec(j);
    end;
  until i>j;
  if l<j then qs(l,j,a);
  if i<r then qs(i,r,a);
end;
procedure minheapify(x:longint);
var min,l,r:longint;
begin
  l:=x shl 1;
  r:=l+1;
  min:=x;
  if (l<=length)and(heap[l].sum<heap[min].sum) then
  min:=l;
  if (r<=length)and(heap[r].sum<heap[min].sum) then
  min:=r;
  if min<>x then
  begin
    heap[0]:=heap[x];
    heap[x]:=heap[min];
    heap[min]:=heap[0];
    minheapify(min);
  end;
end;
procedure sinkup(i:longint);
var parent,tmp:longint;
begin
  parent:=i shr 1;
  if (parent<>0)and(heap[parent].sum>heap[i].sum) then
  begin
    heap[0]:=heap[i];
    heap[i]:=heap[parent];
    heap[parent]:=heap[0];
    if parent>1 then sinkup(parent);
  end;
end;
function popheap:ijk;
var min:ijk;
begin
  if length=0 then exit;
  min:=heap[1];
  heap[1]:=heap[length];
  dec(length);
  minheapify(1);
  exit(min);
end;
procedure pushheap(buf:ijk);
begin
  inc(length);
  heap[length]:=buf;
  if length>1 then
  sinkup(length);
end;
begin
  readln(n);
  for i:=1 to n do
  read(a[i]);
  for i:=1 to n do
  read(b[i]);
  qs(1,n,a);
  qs(1,n,b);
  for i:=1 to n do
  begin
    buf.sum:=a[i]+b[1];
    buf.b:=1;
    pushheap(buf);
  end;
  for i:=1 to n do
  begin
    buf:=popheap;
    if i<>n then write(buf.sum,' ')else writeln(buf.sum);
    if buf.b<=n then
    begin
      buf.sum:=buf.sum-b[buf.b]+b[buf.b+1];
      inc(buf.b);
      pushheap(buf);
    end;
  end;
end.


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值