{"id":15337268,"url":"https://github.com/vy/binomial-heap","last_synced_at":"2025-10-06T19:31:27.402Z","repository":{"id":542037,"uuid":"171935","full_name":"vy/binomial-heap","owner":"vy","description":"The binomial-heap data structure implementation in Common Lisp.","archived":false,"fork":false,"pushed_at":"2013-04-12T11:55:57.000Z","size":112,"stargazers_count":4,"open_issues_count":0,"forks_count":0,"subscribers_count":4,"default_branch":"master","last_synced_at":"2024-11-25T08:36:55.619Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":"","language":"Common Lisp","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":"adldap/adLDAP","license":"bsd-2-clause","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/vy.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null}},"created_at":"2009-04-09T14:20:37.000Z","updated_at":"2024-03-23T16:10:39.000Z","dependencies_parsed_at":"2022-07-07T14:10:22.380Z","dependency_job_id":null,"html_url":"https://github.com/vy/binomial-heap","commit_stats":null,"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/vy%2Fbinomial-heap","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/vy%2Fbinomial-heap/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/vy%2Fbinomial-heap/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/vy%2Fbinomial-heap/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/vy","download_url":"https://codeload.github.com/vy/binomial-heap/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":235546345,"owners_count":19007591,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":[],"created_at":"2024-10-01T10:20:22.511Z","updated_at":"2025-10-06T19:31:22.086Z","avatar_url":"https://github.com/vy.png","language":"Common Lisp","funding_links":[],"categories":[],"sub_categories":[],"readme":"    ___  __ __   ____ _    __ ___  __        _  _ ____ ___  ____\n    | .\\ |_\\| \\|\\|   ||\\/\\ |_\\|  \\ | |   ___ ||_|\\| __\\|  \\ | . \\\n    | .\u003c_| /|  \\|| . ||   \\| /| . \\| |__|___\\| _ ||  ]_| . \\| __/\n    |___/|/ |/\\_/|___/|/v\\/|/ |/\\_/|___/     |/ |/|___/|/\\_/|/\n\n\n# Abstract\n\nBinomial-heap is a compact and  succint implementation of the [binomial heap data structure](http://en.wikipedia.org/wiki/Binomial_heap) in Common Lisp programming language. Insertion,  extremum access, extremum extraction, and union operations are performed in O(logn) time.\n\n\n# Demo\n\n    (defvar *list* (loop repeat 20 collect (random 100)))\n    ; =\u003e (25 50 12 53 53 55 41 71 71 41 33 8 71 57 28 4 89 96 58 25)\n\n    (defvar *heap* (make-instance 'bh:binomial-heap :test #'\u003c))\n    ; =\u003e #\u003cBINOMIAL-HEAP {1002C4EC31}\u003e\n\n    (dolist (item *list*)\n      (insert-key *heap* item))\n    ; =\u003e NIL\n\n    (bh::print-tree (bh::head-of *heap*))\n    ; =\u003e -\u003e ( 2) 25\n    ;      -\u003e ( 1) 89\n    ;        -\u003e ( 0) 96\n    ;      -\u003e ( 0) 58\n    ;    -\u003e ( 4) 4\n    ;      -\u003e ( 3) 12\n    ;        -\u003e ( 2) 41\n    ;          -\u003e ( 1) 53\n    ;            -\u003e ( 0) 55\n    ;          -\u003e ( 0) 71\n    ;        -\u003e ( 1) 25\n    ;          -\u003e ( 0) 50\n    ;        -\u003e ( 0) 53\n    ;      -\u003e ( 2) 8\n    ;        -\u003e ( 1) 41\n    ;          -\u003e ( 0) 71\n    ;        -\u003e ( 0) 33\n    ;      -\u003e ( 1) 57\n    ;        -\u003e ( 0) 71\n    ;      -\u003e ( 0) 28\n    ;    NIL\n\n    (bh:get-extremum-key *heap*)\n    ; =\u003e 4\n\n    (loop for x in (sort (copy-list *list*) (test-of *heap*))\n          for y = (extract-extremum-key *heap*)\n          unless (= x y)\n          collect (cons x y))\n    ; =\u003e NIL\n\n    (let ((h1 (make-instance 'bh:binomial-heap :test #'string\u003c))\n          (h2 (make-instance 'bh:binomial-heap :test #'string\u003c))\n          (l1 '(\"foo\" \"bar\" \"baz\" \"mov\" \"mov\"))\n          (l2 '(\"i\" \"see\" \"dead\" \"binomial\" \"trees\")))\n      (dolist (l l1) (bh:insert-key h1 l))\n      (bh::print-tree (bh::head-of h1))\n    ; =\u003e -\u003e ( 0) \"mov\"\n    ;    -\u003e ( 2) \"bar\"\n    ;      -\u003e ( 1) \"baz\"\n    ;        -\u003e ( 0) \"mov\"\n    ;      -\u003e ( 0) \"foo\"\n    ; NIL\n      (dolist (l l2) (bh:insert-key h2 l))\n      (bh::print-tree (bh::head-of h2))\n    ; =\u003e -\u003e ( 0) \"trees\"\n    ;    -\u003e ( 2) \"binomial\"\n    ;      -\u003e ( 1) \"i\"\n    ;        -\u003e ( 0) \"see\"\n    ;      -\u003e ( 0) \"dead\"\n    ; NIL\n      (let ((h3 (bh:unite-heaps h1 h2)))\n        (bh::print-tree (bh::head-of h3))))\n    ; =\u003e -\u003e ( 1) \"mov\"\n    ;      -\u003e ( 0) \"trees\"\n    ;    -\u003e ( 3) \"bar\"\n    ;      -\u003e ( 2) \"binomial\"\n    ;        -\u003e ( 1) \"i\"\n    ;          -\u003e ( 0) \"see\"\n    ;        -\u003e ( 0) \"dead\"\n    ;      -\u003e ( 1) \"baz\"\n    ;        -\u003e ( 0) \"mov\"\n    ;      -\u003e ( 0) \"foo\"\n    ; NIL\n\n# Caveats\n\nDespite binomial  heaps are  known to perform  decrease/increase key  and delete operations in O(logn) time, this is practically not that easy to implement. (For the rest  of this talk, I'll  skip the deletion  operation because of it  can be achieved through  setting the key  field of a  node to the absolute  extremum -- i.e.  negative infinity -- and extracting the extremum.) Consider below example.\n\n    --\u003e [ Z ] --\u003e\n          ^\n          |\n          |\n    --\u003e [ X ] --\u003e\n         ^^^\n         |||\n         ||+----------------------------+\n         |+----------+        ...       |\n         |           |                  |\n    --\u003e [ W0 ] --\u003e [ W1 ] --\u003e ... --\u003e [ WN ]\n\nSuppose you decreased the key field of X and you need to bubble up X by swapping nodes  in upwards  direction  appropriately.  Because of  random access is  not possible  in heap  data  structures, you  need to  figure  out your  own way  of accessing to nodes -- in this  example consider you have the pointers in advance to the  every `BINOMIAL-TREE` in the `BINOMIAL-HEAP`. There are two  ways to swap nodes:\n\n## Swapping Key Fields\n\nIf you just swap the key fields of the nodes\n\n    (rotatef (key-of x) (key-of z))\n\neverything will be fine, except that the pointers to the nodes that lost their original  key fields  will  get  invalidated.  Now  you  cannot guarantee the validity of  your node pointers and  hence cannot issue any  more decrease key operations.\n\n## Swapping Node Instances\n\nIf you  swap the two node  instances, your pointers won't  get invalidated but this time you'll need to update the sibling and parent pointers as well,\n\n    (setf (parent-of w0) z\n          (parent-of w1) z\n    ...\n    (parent-of wn) z)\n\nwhich will make  your O(logn) complexity dreams fade  away.  (Moreover, you'll need to traverse sibling  lists at levels of nodes `X` and `Y` to be able to find previous siblings to `X` and `Y` if you are not using doubly-linked-lists. But even this scheme doesn't save us from the traversal of `W1`, ..., `WN` nodes.)\n\n## Solution\n\nSo how can we manage to perform decrease key operation in O(logn) time without invalidating any node pointers? The solution I come up with to this problem is as follows.\n\nWe can keep a separate hash table for the pointers to the nodes. When a node's key  field  gets modified,  related  hash table  entry  will  get modified  as well. And instead of returning to the user the actual `BINOMIAL-TREE` instances, we'll return  to the user the key  of the related hash  table entry. (Consider this hash table  as a mapping between  the hash table keys and  the pointer to the actual node instance.)\n\nSounds too hairy? I think so. I'd be appreciated for any sort of enlightenment of a better solution.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fvy%2Fbinomial-heap","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fvy%2Fbinomial-heap","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fvy%2Fbinomial-heap/lists"}