shithub: asif

Download patch

ref: 6c9eb7f74993179a823f4e1c02793786d51bf773
author: qwx <qwx@sciops.net>
date: Tue Aug 11 07:33:22 EDT 2020

add pairing heaps

--- /dev/null
+++ b/fns.h
@@ -1,0 +1,4 @@
+void	nukequeue(Pairheap**);
+Pairheap*	popqueue(Pairheap**);
+void	decreasekey(Pairheap*, double, Pairheap**);
+void	pushqueue(double, void*, Pairheap**);
--- /dev/null
+++ b/heap.h
@@ -1,0 +1,9 @@
+typedef struct Pairheap Pairheap;
+
+struct Pairheap{
+	double n;
+	void *aux;
+	Pairheap *parent;
+	Pairheap *left;
+	Pairheap *right;
+};
--- /dev/null
+++ b/pheap.c
@@ -1,0 +1,83 @@
+#include <u.h>
+#include <libc.h>
+#include "heap.h"
+#include "fns.h"
+
+static Pairheap *
+mergequeue(Pairheap *a, Pairheap *b)
+{
+	if(b == nil)
+		return a;
+	else if(a->n < b->n){
+		b->right = a->left;
+		a->left = b;
+		b->parent = a;
+		return a;
+	}else{
+		a->right = b->left;
+		b->left = a;
+		a->parent = b;
+		return b;
+	}
+}
+
+static Pairheap *
+mergepairs(Pairheap *a)
+{
+	Pairheap *b, *c;
+
+	if(a == nil)
+		return nil;
+	a->parent = nil;
+	b = a->right;
+	if(b == nil)
+		return a;
+	a->right = nil;
+	b->parent = nil;
+	c = b->right;
+	b->right = nil;
+	return mergequeue(mergequeue(a, b), mergepairs(c));
+}
+
+void
+nukequeue(Pairheap **queue)
+{
+	Pairheap *p;
+
+	while((p = popqueue(queue)) != nil)
+		free(p);
+}
+
+Pairheap *
+popqueue(Pairheap **queue)
+{
+	Pairheap *p;
+
+	p = *queue;
+	if(p == nil)
+		return nil;
+	*queue = mergepairs(p->left);
+	return p;
+}
+
+void
+decreasekey(Pairheap *p, double Δ, Pairheap **queue)
+{
+	p->n -= Δ;
+	if(p->parent != nil && p->n < p->parent->n){
+		p->parent->left = nil;
+		p->parent = nil;
+		*queue = mergequeue(p, *queue);
+	}
+}
+
+void
+pushqueue(int n, void *aux, Pairheap **queue)
+{
+	Pairheap *p;
+
+	p = emalloc(sizeof *p);
+	p->n = n;
+	p->aux = aux;
+	*queue = mergequeue(p, *queue);
+}