caml-list - the Caml user's mailing list
 help / color / mirror / Atom feed
From: Eray Ozkural <exa@kablonet.com.tr>
To: OCaml List <caml-list@inria.fr>
Subject: [Caml-list] heapsort and priority queue code
Date: Mon, 28 Apr 2003 03:19:43 +0300	[thread overview]
Message-ID: <200304280319.43986.exa@kablonet.com.tr> (raw)

[-- Attachment #1: Type: text/plain, Size: 477 bytes --]

Hi there,

Here is a version of heap sort and PQ ops, maybe you have a use for it who 
knows :) Any suggested improvements over style will be carefully listened to.

license is GPL :P

Regards,

-- 
Eray Ozkural (exa) <erayo@cs.bilkent.edu.tr>
Comp. Sci. Dept., Bilkent University, Ankara  KDE Project: http://www.kde.org
www: http://www.cs.bilkent.edu.tr/~erayo  Malfunction: http://mp3.com/ariza
GPG public key fingerprint: 360C 852F 88B0 A745 F31B  EA0F 7C07 AE16 874D 539C

[-- Warning: decoded text below may be mangled, UTF-8 assumed --]
[-- Attachment #2: heap.ml --]
[-- Type: text/plain; charset="us-ascii"; name="heap.ml", Size: 1825 bytes --]

open Array
open Printf

type heap = { a: int array; mutable size: int }

let swap a i j = let t = a.(i) in a.(i) <- a.(j); a.(j) <- t
let print_intarray a = Array.iter (fun x->printf "%d " x) a

(* arrays start from 0 *)
(* a heap array, i index *)

let parent i = (i-1) / 2
let left i = 2*i + 1
let right i = 2*i + 2

let rec heapify h i =
  let l = ref (left i)
  and r = ref (right i)
  and largest = ref 0
  and a = h.a in
    printf "i=%d, l=%d, r=%d, hs=%d\n" i !l !r h.size;
    if !l < h.size && a.(!l) > a.(i)
    then largest := !l
    else largest := i;
    if !r < h.size && a.(!r) > a.(!largest)
    then largest := !r else ();
    if !largest <> i then
      begin
	swap a i !largest;
	heapify h !largest
      end
    else ()

let build_heap a =
  let h = { a = a; size = length a} in
    for i = (length a)/2-1 downto 0 do heapify h i done;
    h

let sort a =
  let h = build_heap a in
    for i = length a-1 downto 1 do
      swap a 0 i;
      h.size <- h.size-1;
      heapify h 0
    done

exception Underflow

let extract_max h =
  if h.size < 1 then raise Underflow else
    let a = h.a in
    let max = a.(0) in
      a.(0) <- a.(h.size-1);
      h.size <- h.size - 1;
      heapify h 0;
      max
      
let insert h key =
  h.size <- h.size + 1;
  let i = ref (h.size - 1) in (* last node *)
  let a = h.a in
    while !i > 0 && a.(parent !i) < key do
      a.(!i) <- a.(parent !i);
      i := parent !i
    done;
    a.(!i) <- key

let test () =
  begin
    let a = [| 5; 13; 2; 25; 7; 16; 20; 8; 4 |] in
      sort a;
      print_intarray a; printf "\n"
  end;
  begin
    let h = {a = [| 15;13;9;5;12;8;7;4;0;6;2;1;0;0;0 |]; size=12} in
      insert h 3
  end;
  begin
    let h = {a = [| 15;13;9;5;12;8;7;4;0;6;2;1 |]; size=12} in
    let t = extract_max h in
      printf "top is %d\n" t
  end


                 reply	other threads:[~2003-04-28  0:20 UTC|newest]

Thread overview: [no followups] expand[flat|nested]  mbox.gz  Atom feed

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=200304280319.43986.exa@kablonet.com.tr \
    --to=exa@kablonet.com.tr \
    --cc=caml-list@inria.fr \
    --cc=erayo@cs.bilkent.edu.tr \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).