[ create a new paste ] login | about

Link: http://codepad.org/vKEivBGq    [ raw code | fork ]

C, pasted on May 7:
#include <math.h>
#include <stdlib.h>

typedef struct RedBlackTreeNode
{
	int							key;
	long double					count;
	int							color;
	struct	RedBlackTreeNode*	left;
	struct	RedBlackTreeNode*	right;
}rbtree;

static rbtree* RedBlackTree_insert(rbtree *p, int key, long double count);
static rbtree* RedBlackTree_find(rbtree *p, int key);
static void RedBlackTree_free(rbtree *p);
long double partition_numbers_imp(int n, rbtree **rootp);

long double partition_numbers(int n)
{
	long double count;
	rbtree *root = NULL;

	count = partition_numbers_imp(n, &root);
	RedBlackTree_free(root);
	return count;
}

long double partition_numbers_imp(int n, rbtree **rootp)
{
	int k;
	long double count;
	rbtree *p;

	if(n < 0)
		return 0.0;
	if(n == 0)
		return 1.0;

	/* if the count for n is already added in tree, return the count directly from tree */
	if((p = RedBlackTree_find(*rootp, n)) != NULL)
		return p->count;

	for(k = 1, count = 0; k <= n; k++)
		count += pow((long double)(-1), k+1) * (partition_numbers_imp(n - ((k*(3*k-1))/2), rootp) + partition_numbers_imp(n - ((k*(3*k+1))/2), rootp));

	/* remember the the count for n in redblack tree */
	if((p = RedBlackTree_find(*rootp, n)) == NULL)
		*rootp = RedBlackTree_insert(*rootp, n, count);
	return count;
}



static rbtree* RedBlackTree_insert_imp(rbtree *p, int key, long double count, int direction);
static rbtree* rightRotation(rbtree *p);
static rbtree* leftRotation(rbtree *p);
static rbtree* create_node(int key, long double count);

enum {BLACK = 0, RED};
enum {LEFT = 0, RIGHT};

/* insert function */
static rbtree* RedBlackTree_insert(rbtree *p, int key, long double count)
{
	rbtree *root;

	root = RedBlackTree_insert_imp(p, key, count, LEFT);

	/* the color of root should always be black */
	root->color = BLACK;
	return root;
}

/* lookup function */
static rbtree* RedBlackTree_find(rbtree *p, int key)
{
	while(p)
	{
		if(p->key == key)
			return p;
		else if(key < p->key)
			p = p->left;
		else
			p = p->right;
	}
	return NULL;
}

static void RedBlackTree_free(rbtree *p)
{
	if(p == NULL)
		return;

	RedBlackTree_free(p->left);
	RedBlackTree_free(p->right);
	free(p);
}

static rbtree* RedBlackTree_insert_imp(rbtree *p, int key, long double count, int direction)
{
	if(p == NULL)
		return create_node(key, count);

	/* while moving from top to bottom, check for 4-nodes and split them*/
	if(p->left != NULL && p->right != NULL)
	{
		if((p->left->color == RED) && (p->right->color == RED))
		{
			/* split the 4-node into two 2-nodes by changing the color of left and right
				child from red to black. Also, convert the parent of 4-node from n-node to (n+1)-node */
			p->color = RED;
			p->left->color = BLACK;
			p->right->color = BLACK;
		}
	}

	if(key < p->key)
	{
		/* move to left subtree */
		p->left = RedBlackTree_insert_imp(p->left, key, count, LEFT);

		/* three nodes are connected by red links. the nodes orientation is n1--right--p--left-n3.
			rotate p right */
		if(p->color == RED			&&
			p->left->color == RED	&&
			direction == RIGHT)
		{
			p = rightRotation(p);
		}

		/* three nodes are connected by red links. the nodes orientation is n1--left--p--left-n3.
			rotate p right */
		if(p->left != NULL			&&
			p->left->left != NULL	&&
			p->left->color == RED	&&
			p->left->left->color == RED)
		{
			p = rightRotation(p);

			/* change the color of p to black and right child to red */
			p->color = BLACK;
			p->right->color = RED;
		}
	}
	else
	{
		/* move to right subtree */
		p->right = RedBlackTree_insert_imp(p->right, key, count, RIGHT);

		/* three nodes are connected by red links. the nodes orientation is n1--left--p--right-n3.
			rotate p left */
		if(p->color == RED			&&
			p->right->color == RED	&&
			direction == LEFT)
		{
			p = leftRotation(p);
		}

		/* three nodes are connected by red links. the nodes orientation is n1--right--p--right-n3.
			rotate p left */
		if(p->right != NULL			&&
			p->right->right != NULL	&&
			p->right->color == RED	&&
			p->right->right->color == RED)
		{
			p = leftRotation(p);

			/* change the color of p to black and right child to red */
			p->color = BLACK;
			p->left->color = RED;
		}
	}

	return p;
}

static rbtree* create_node(int key, long double count)
{
	rbtree *p;

	p = (rbtree*)malloc(sizeof(*p));

	if(p == NULL)
		return NULL;

	p->color = RED;
	p->key = key;
	p->count = count;
	p->left = p->right = NULL;
	return p;
}

static rbtree* rightRotation(rbtree *p)
{
	rbtree *ptr = p->left;

	p->left = ptr->right;
	ptr->right = p;

	return ptr;
}

static rbtree* leftRotation(rbtree *p)
{
	rbtree *ptr = p->right;

	p->right = ptr->left;
	ptr->left = p;

	return ptr;
}


Create a new paste based on this one


Comments: