알고리즘 서론 코드 제1 4 장 데이터 구조의 확장

20110 단어
제1 4 장 데이터 구조의 확장
14.1 동적 순서 통계
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
typedef struct red_black_tree_type *tree;
enum color_enum {
	color_red,
	color_black
};
struct tree_node {
	void *key;
	enum color_enum color;
	struct tree_node *parent;
	struct tree_node *left;
	struct tree_node *right;
	int size;
};

struct red_black_tree_type {
	int (*comp)(const void*,const void*);
	struct tree_node *root;
	struct tree_node *nil;
};
void tree_node_ini(struct tree_node *p, void *key)
{
	p->key = key;
	p->parent = NULL;
	p->left = NULL;
	p->right = NULL;
	p->color = color_black;
	p->size = 0;
}

void tree_left_rotate(tree t, struct tree_node *x)
{
	struct tree_node *y = x->right;
	x->right = y->left;
	y->left->parent = x;
	y->parent = x->parent;
	if (x->parent == t->nil) {
		t->root = y;
	} else {
		if (x == x->parent->left) {
			x->parent->left = y;
		} else {
			x->parent->right = y;
		}
	}
	y->left = x;
	x->parent = y;
	y->size = x->size;
	x->size = x->left->size + x->right->size + 1;
}

void tree_right_rotate(tree t, struct tree_node *x)
{
	struct tree_node *y = x->left;
	x->left = y->right;
	y->right->parent = x;
	y->parent = x->parent;
	if (x->parent == t->nil) {
		t->root = y;
	} else {
		if (x == x->parent->left) {
			x->parent->left = y;
		} else {
			x->parent->right = y;
		}
	}
	y->right = x;
	x->parent = y;
	y->size = x->size;
	x->size = x->left->size + x->right->size + 1;
}

tree tree_create(int (*comp)(const void*,const void*))
{
	tree t = malloc(sizeof(struct red_black_tree_type));
	t->nil = malloc(sizeof(struct tree_node));
	t->comp=comp;
	tree_node_ini(t->nil, NULL);
	t->root = t->nil;
	return t;
}

void tree_destroy_all_node(tree t, struct tree_node *x, void (*free_key) (void *))
{
	if (x != t->nil) {
		tree_destroy_all_node(t, x->left, free_key);
		tree_destroy_all_node(t, x->right, free_key);
		free_key(x->key);
		free(x);
	}
}

void tree_destroy(tree t, void (*free_key) (void *))
{
	tree_destroy_all_node(t, t->root, free_key);
	free(t->nil);
	free(t);
}

void tree_inorder_tree_walk(tree t, struct tree_node *x,
			    void (*handle) (const void *))
{
	if (x != t->nil) {
		tree_inorder_tree_walk(t, x->left, handle);
		handle(x->key);
		tree_inorder_tree_walk(t, x->right, handle);
	}
}

struct tree_node *tree_search(tree t, struct tree_node *x, void *key,
			      int (*comp) (const void *, const void *))
{
	if (x == t->nil || comp(key, x->key) == 0) {
		return x;
	}
	if (comp(key, x->key) < 0) {
		return tree_search(t, x->left, key, comp);
	} else {
		return tree_search(t, x->right, key, comp);
	}
}

struct tree_node *tree_minimum(tree t, struct tree_node *x)
{
	while (x != t->nil && x->left != t->nil) {
		x = x->left;
	}
	return x;
}

struct tree_node *tree_successor(tree t, struct tree_node *x)
{
	if (x->right != t->nil) {
		return tree_minimum(t, x->right);
	}
	struct tree_node *y = x->parent;
	while (y != t->nil && x == y->right) {
		x = y;
		y = y->parent;
	}
	return y;
}

void tree_insert_fixup(tree t, struct tree_node *z)
{
	struct tree_node *y = t->nil;
	while (z->parent->color == color_red) {
		if (z->parent == z->parent->parent->left) {
			y = z->parent->parent->right;
			//  1:z   y    
			if (y->color == color_red) {
				z->parent->color = color_black;
				y->color = color_black;
				z->parent->parent->color = color_red;
				z = z->parent->parent;
			} else {
				//  2:z   y    ,z    
				if (z == z->parent->right) {
					z = z->parent;
					tree_left_rotate(t, z);
				}
				//  3:z   y    ,z    
				z->parent->color = color_black;
				z->parent->parent->color = color_red;
				tree_right_rotate(t, z->parent->parent);
			}
		} else {
			y = z->parent->parent->left;
			if (y->color == color_red) {
				z->parent->color = color_black;
				y->color = color_black;
				z->parent->parent->color = color_red;
				z = z->parent->parent;
			} else {
				if (z == z->parent->left) {
					z = z->parent;
					tree_right_rotate(t, z);
				}
				z->parent->color = color_black;
				z->parent->parent->color = color_red;
				tree_left_rotate(t, z->parent->parent);
			}
		}
	}
	t->root->color = color_black;
}

void tree_insert(tree t, struct tree_node *z)
{
	struct tree_node *y = t->nil;
	struct tree_node *x = t->root;
	while (x != t->nil) {
		y = x;
		++y->size;
		if (t->comp(z->key, x->key) < 0) {
			x = x->left;
		} else {
			x = x->right;
		}
	}
	z->parent = y;
	if (y == t->nil) {
		t->root = z;
	} else {
		if (t->comp(z->key, y->key) < 0) {
			y->left = z;
		} else {
			y->right = z;
		}
	}
	z->left = t->nil;
	z->right = t->nil;
	z->color = color_red;
	z->size=1;
	tree_insert_fixup(t, z);
}

void tree_delete_fixup(tree t, struct tree_node *x)
{
	struct tree_node *w = t->nil;
	while (x != t->root && x->color == color_black) {
		if (x == x->parent->left) {
			w = x->parent->right;
			//  1:x   w    
			if (w->color == color_red) {
				w->color = color_black;
				x->parent->color = color_red;
				tree_left_rotate(t, x->parent);
				w = x->parent->right;
			} else {
				//  2:x   w    ,  w          
				if (w->left->color == color_black
				    && w->right->color == color_black) {
					w->color = color_red;
					x = x->parent;
				} else {
					//  3:x   w    ,w       ,      
					if (w->right->color == color_black) {
						w->left->color = color_black;
						w->color = color_red;
						tree_right_rotate(t, w);
						w = x->parent->right;
					}
					//  4:x   w    ,  w        
					w->color = x->parent->color;
					x->parent->color = color_black;
					w->right->color = color_black;
					tree_left_rotate(t, x->parent);
					x = t->root;
				}
			}
		} else {
			w = x->parent->left;
			if (w->color == color_red) {
				w->color = color_black;
				x->parent->color = color_red;
				tree_right_rotate(t, x->parent);
				w = x->parent->left;
			} else {
				if (w->right->color == color_black
				    && w->left->color == color_black) {
					w->color = color_red;
					x = x->parent;
				} else {
					if (w->left->color == color_black) {
						w->right->color = color_black;
						w->color = color_red;
						tree_left_rotate(t, w);
						w = x->parent->left;
					}
					w->color = x->parent->color;
					x->parent->color = color_black;
					w->left->color = color_black;
					tree_right_rotate(t, x->parent);
					x = t->root;
				}
			}
		}
	}
	x->color = color_black;
}

void swap(void *a, void *b, size_t elem_size)
{
	if (a == NULL || b == NULL || a == b)
		return;
	char temp[elem_size];	/*     */
	memcpy(temp, a, elem_size);
	memcpy(a, b, elem_size);
	memcpy(b, temp, elem_size);
}

struct tree_node *tree_delete(tree t, struct tree_node *z)
{
	struct tree_node *y;
	struct tree_node *x;
	if (z->left == t->nil || z->right == t->nil) {
		y = z;
	} else {
		y = tree_successor(t, z);
	}
	if (y->left != t->nil) {
		x = y->left;
	} else {
		x = y->right;
	}
	x->parent = y->parent;
	if (y->parent == t->nil) {
		t->root = x;
	} else {
		if (y == y->parent->left) {
			y->parent->left = x;
		} else {
			y->parent->right = x;
		}
	}
	if (y != z) {
		/*      y z   ,  z y      */
		swap(&z->key, &y->key, sizeof(void *));
	}
	struct tree_node *p = y;
	do {
		p = p->parent;
		--p->size;
	} while (p != t->root);	/*  size */
	if (y->color == color_black) {
		tree_delete_fixup(t, x);
	}
	return y;
}

/*           */
struct tree_node *tree_select(struct tree_node *x, int i)
{
	int r = x->left->size + 1;
	if (i == r) {
		return x;
	} else {
		if (i < r) {
			return tree_select(x->left, i);
		} else {
			return tree_select(x->right, i - r);
		}
	}
}

/*        */
int tree_rank(tree t, struct tree_node *x)
{
	int r = x->left->size + 1;
	struct tree_node *y = x;
	while (y != t->root) {
		if (y == y->parent->right) {
			r = r + y->parent->left->size + 1;
		}
		y = y->parent;
	}
	return r;
}

void print_key(const void *key)
{
	const int *p = key;
	printf("%d ", *p);
}

int cmp_int(const void *p1, const void *p2)
{
	const int *pa = p1;
	const int *pb = p2;
	if (*pa < *pb)
		return -1;
	if (*pa == *pb)
		return 0;
	return 1;
}
int main()
{
	tree t = tree_create(cmp_int);
	for (int i = 0; i < 10; i++) {
		struct tree_node *node = malloc(sizeof(struct tree_node));
		int *ip = malloc(sizeof(int));
		*ip = i;
		tree_node_ini(node, ip);
		tree_insert(t, node);
	}
	printf("      :
"); tree_inorder_tree_walk(t, t->root, print_key); printf("
"); int rank = tree_rank(t, t->root); printf(" :%d, :%d,Size:%d
", *(int *)t->root->key, rank, t->root->size); rank = 6; struct tree_node *node = tree_select(t->root, rank); printf(" %d :%d
", rank, *(int *)node->key); printf(" %d :
", rank); struct tree_node *del_node = tree_delete(t, node); free(del_node->key); free(del_node); tree_inorder_tree_walk(t, t->root, print_key); printf("
"); rank = tree_rank(t, t->root); printf(" , :%d, :%d,Size:%d
", *(int *)t->root->key, rank, t->root->size); /* , key */ tree_destroy(t, free); return 0; }

14.3 구간 수
#include <stdio.h>
#include <time.h>
#include <stdbool.h>
#include <string.h>
#include <stdlib.h>
#define	MAX(a,b) (((a)>(b))?(a):(b))
typedef struct red_black_tree_type *tree;
enum color_enum {
	color_red,
	color_black
};
struct interval {
	int low;
	int hight;
};

struct tree_node {
	struct interval it;
	enum color_enum color;
	struct tree_node *parent;
	struct tree_node *left;
	struct tree_node *right;
	int interval_max;
};

struct red_black_tree_type {
	struct tree_node *root;
	struct tree_node *nil;
};
void interval_ini(struct interval *it, int low, int hight)
{
	it->low = low;
	it->hight = hight;
}

bool interval_is_overlap(struct interval *it_a, struct interval *it_b)
{
	if (it_a->low <= it_b->hight && it_b->low <= it_a->hight) {
		return true;
	} else {
		return false;
	}
}

void tree_node_ini(struct tree_node *p, struct interval *it)
{
	p->it = *it;
	p->interval_max = it->hight;
	p->parent = NULL;
	p->left = NULL;
	p->right = NULL;
	p->color = color_black;
}

void tree_left_rotate(tree t, struct tree_node *x)
{
	struct tree_node *y = x->right;
	x->right = y->left;
	y->left->parent = x;
	y->parent = x->parent;
	if (x->parent == t->nil) {
		t->root = y;
	} else {
		if (x == x->parent->left) {
			x->parent->left = y;
		} else {
			x->parent->right = y;
		}
	}
	y->left = x;
	x->parent = y;
	y->interval_max = x->interval_max;
	int max = MAX(x->left->interval_max, x->right->interval_max);
	x->interval_max = MAX(x->it.hight, max);
}

void tree_right_rotate(tree t, struct tree_node *x)
{
	struct tree_node *y = x->left;
	x->left = y->right;
	y->right->parent = x;
	y->parent = x->parent;
	if (x->parent == t->nil) {
		t->root = y;
	} else {
		if (x == x->parent->left) {
			x->parent->left = y;
		} else {
			x->parent->right = y;
		}
	}
	y->right = x;
	x->parent = y;
	y->interval_max = x->interval_max;
	int max = MAX(x->left->interval_max, x->right->interval_max);
	x->interval_max = MAX(x->it.hight, max);
}

tree tree_create()
{
	tree t = malloc(sizeof(struct red_black_tree_type));
	t->nil = malloc(sizeof(struct tree_node));
	tree_node_ini(t->nil, &(struct interval) {
		      0, 0});
	t->root = t->nil;
	return t;
}

void tree_delete_node(tree t, struct tree_node *x)
{
	if (x != t->nil) {
		tree_delete_node(t, x->left);
		tree_delete_node(t, x->right);
		free(x);
	}
}

void tree_destroy(tree t)
{
	tree_delete_node(t, t->root);
	free(t->nil);
	free(t);
}

void tree_inorder_tree_walk(tree t, struct tree_node *x,
			    void (*handle) (struct interval *))
{
	if (x != t->nil) {
		tree_inorder_tree_walk(t, x->left, handle);
		handle(&x->it);
		tree_inorder_tree_walk(t, x->right, handle);
	}
}

struct tree_node *tree_interval_search(tree t, struct interval *it)
{
	struct tree_node *x = t->root;
	while (x != t->nil && !interval_is_overlap(&x->it, it)) {
		if (x->left != t->nil && x->left->interval_max >= it->low) {
			x = x->left;
		} else {
			x = x->right;
		}
	}
	return x;
}

struct tree_node *tree_minimum(tree t, struct tree_node *x)
{
	while (x != t->nil && x->left != t->nil) {
		x = x->left;
	}
	return x;
}

struct tree_node *tree_successor(tree t, struct tree_node *x)
{
	if (x->right != t->nil) {
		return tree_minimum(t, x->right);
	}
	struct tree_node *y = x->parent;
	while (y != t->nil && x == y->right) {
		x = y;
		y = y->parent;
	}
	return y;
}

void tree_insert_fixup(tree t, struct tree_node *z)
{
	struct tree_node *y = t->nil;
	while (z->parent->color == color_red) {
		if (z->parent == z->parent->parent->left) {
			y = z->parent->parent->right;
			//  1:z   y    
			if (y->color == color_red) {
				z->parent->color = color_black;
				y->color = color_black;
				z->parent->parent->color = color_red;
				z = z->parent->parent;
			} else {
				//  2:z   y    ,z    
				if (z == z->parent->right) {
					z = z->parent;
					tree_left_rotate(t, z);
				}
				//  3:z   y    ,z    
				z->parent->color = color_black;
				z->parent->parent->color = color_red;
				tree_right_rotate(t, z->parent->parent);
			}
		} else {
			y = z->parent->parent->left;
			if (y->color == color_red) {
				z->parent->color = color_black;
				y->color = color_black;
				z->parent->parent->color = color_red;
				z = z->parent->parent;
			} else {
				if (z == z->parent->left) {
					z = z->parent;
					tree_right_rotate(t, z);
				}
				z->parent->color = color_black;
				z->parent->parent->color = color_red;
				tree_left_rotate(t, z->parent->parent);
			}
		}
	}
	t->root->color = color_black;
}

void tree_insert(tree t, struct tree_node *z)
{
	struct tree_node *y = t->nil;
	struct tree_node *x = t->root;
	while (x != t->nil) {
		y = x;
		y->interval_max = MAX(y->interval_max, z->interval_max);
		if (z->it.low < x->it.low) {
			x = x->left;
		} else {
			x = x->right;
		}
	}
	z->parent = y;
	if (y == t->nil) {
		t->root = z;
	} else {
		if (z->it.low < y->it.low) {
			y->left = z;
		} else {
			y->right = z;
		}
	}
	z->left = t->nil;
	z->right = t->nil;
	z->color = color_red;
	tree_insert_fixup(t, z);
}

void tree_delete_fixup(tree t, struct tree_node *x)
{
	struct tree_node *w = t->nil;
	while (x != t->root && x->color == color_black) {
		if (x == x->parent->left) {
			w = x->parent->right;
			//  1:x   w    
			if (w->color == color_red) {
				w->color = color_black;
				x->parent->color = color_red;
				tree_left_rotate(t, x->parent);
				w = x->parent->right;
			} else {
				//  2:x   w    ,  w          
				if (w->left->color == color_black
				    && w->right->color == color_black) {
					w->color = color_red;
					x = x->parent;
				} else {
					//  3:x   w    ,w       ,      
					if (w->right->color == color_black) {
						w->left->color = color_black;
						w->color = color_red;
						tree_right_rotate(t, w);
						w = x->parent->right;
					}
					//  4:x   w    ,  w        
					w->color = x->parent->color;
					x->parent->color = color_black;
					w->right->color = color_black;
					tree_left_rotate(t, x->parent);
					x = t->root;
				}
			}
		} else {
			w = x->parent->left;
			if (w->color == color_red) {
				w->color = color_black;
				x->parent->color = color_red;
				tree_right_rotate(t, x->parent);
				w = x->parent->left;
			} else {
				if (w->right->color == color_black
				    && w->left->color == color_black) {
					w->color = color_red;
					x = x->parent;
				} else {
					if (w->left->color == color_black) {
						w->right->color = color_black;
						w->color = color_red;
						tree_left_rotate(t, w);
						w = x->parent->left;
					}
					w->color = x->parent->color;
					x->parent->color = color_black;
					w->left->color = color_black;
					tree_right_rotate(t, x->parent);
					x = t->root;
				}
			}
		}
	}
	x->color = color_black;
}

void swap(void *a, void *b, size_t elem_size)
{
	if (a == NULL || b == NULL || a == b)
		return;
	char temp[elem_size];	/*     */
	memcpy(temp, a, elem_size);
	memcpy(a, b, elem_size);
	memcpy(b, temp, elem_size);
}

struct tree_node *tree_delete(tree t, struct tree_node *z)
{
	struct tree_node *y;
	struct tree_node *x;
	if (z->left == t->nil || z->right == t->nil) {
		y = z;
	} else {
		y = tree_successor(t, z);
	}
	if (y->left != t->nil) {
		x = y->left;
	} else {
		x = y->right;
	}
	x->parent = y->parent;
	if (y->parent == t->nil) {
		t->root = x;
	} else {
		if (y == y->parent->left) {
			y->parent->left = x;
		} else {
			y->parent->right = x;
		}
	}
	if (y != z) {
		/*      y z   ,  z y      */
		swap(&z->it, &y->it, sizeof(struct interval));
	}
	struct tree_node *p = y;
	do {
		p = p->parent;
		int max = MAX(p->left->interval_max, p->right->interval_max);
		p->interval_max = MAX(p->it.hight, max);
	} while (p != t->root);	/*  interval_max */
	if (y->color == color_black) {
		tree_delete_fixup(t, x);
	}
	return y;
}

void print_interval(struct interval *it)
{
	printf("(%d,%d)", it->low, it->hight);
}

int main()
{
	srand((unsigned)time(NULL));
	tree t = tree_create();
	for (int i = 0; i < 10; i++) {
		struct tree_node *node = malloc(sizeof(struct tree_node));
		struct interval it;
		interval_ini(&it, i, i + rand() % 10);
		tree_node_ini(node, &it);
		tree_insert(t, node);
	}
	printf("      :
"); tree_inorder_tree_walk(t, t->root, print_interval); printf("
"); printf(" :(%d,%d), :%d
", t->root->it.low, t->root->it.hight, t->root->interval_max); struct interval it = { 10, 15 }; printf(" :(%d,%d) :
", it.low, it.hight); struct tree_node *result = tree_interval_search(t, &it); printf(" :%s
", result != t->nil ? " " : " "); if (result != t->nil) { printf(" :(%d,%d)
", result->it.low, result->it.hight); printf(" :(%d,%d)
", result->it.low, result->it.hight); struct tree_node *del_node = tree_delete(t, result); free(del_node); printf(" :
"); tree_inorder_tree_walk(t, t->root, print_interval); printf("
"); printf(" , :(%d,%d), :%d
", t->root->it.low, t->root->it.hight, t->root->interval_max); } /* , key */ tree_destroy(t); return 0; }

좋은 웹페이지 즐겨찾기