二叉树,红黑树 (C 实现)

以下代码只经过少量的测试,如有问题,可回复 。


二叉搜索树:


#include <stdio.h>
#include <stdlib.h>


#define ROOT(_T_)	(_T_->left)
#define LEFT(_T_)	(_T_->left)
#define RIGHT(_T_)	(_T_->right)
#define PARENT(_T_)	(_T_->parent)
#define KEY(_T_)	(_T_->key)
#define NIL	NULL


struct Tree
{
	int key;
	struct Tree *left;
	struct Tree *right;
	struct Tree *parent;
};


void insert(struct Tree *T, struct Tree *z)
{
	struct Tree *x = ROOT(T);
	struct Tree *y = NIL;
	while (NIL != x)
	{
		y = x;
		if (KEY(x) < KEY(z))
		{
			x = RIGHT(x);
		}
		else
		{
			x = LEFT(x);
		}
	}
	PARENT(z) = y;
	if (NIL == y)
	{
		ROOT(T) = z;
	}
	else if (KEY(y) < KEY(z))
	{
		RIGHT(y) = z;
	}
	else
	{
		LEFT(y) = z;
	}
}


void creat(struct Tree *T)
{
	int key = 0;
	while (EOF != scanf("%d", &key))
	{
		struct Tree *z = (struct Tree *)malloc(sizeof(struct Tree));
		PARENT(z) = NIL;
		LEFT(z) = NIL;
		RIGHT(z) = NIL;
		KEY(z) = key;
		insert(T, z);
	}
}



struct Tree *search(struct Tree *x, int k)
{
	while ((NIL != x) && (k != KEY(x)))
	{
		if (KEY(x) < k)
		{
			x = RIGHT(x);
		}
		else
		{
			x = LEFT(x);
		}
	}
	return x;
}


void left_mid_right(struct Tree *x)
{
	if (NIL != x)
	{
		left_mid_right(LEFT(x));
		printf("%d---", KEY(x));
		left_mid_right(RIGHT(x));
	}
}


void mid_left_right(struct Tree *x)
{
	if (NIL != x)
	{
		printf("%d---", KEY(x));
		mid_left_right(LEFT(x));
		mid_left_right(RIGHT(x));
	}
}


struct Tree *min(struct Tree *x)
{
	while (NIL != LEFT(x))
	{
		x = LEFT(x);
	}
	return x;
}


struct Tree *max(struct Tree *x)
{
	while (NIL != RIGHT(x))
	{
		x = RIGHT(x);
	}
	return x;
}


struct Tree *min(struct Tree *x)
{
	while (NIL != LEFT(x))
	{
		x = LEFT(x);
	}
	return x;
}


struct Tree *successor(struct Tree *x)
{
	if (NIL != RIGHT(x))
	{
		return min(RIGHT(x));
	}
	struct Tree *y = PARENT(x);
	while ((NIL != y) && (x == RIGHT(y)))
	{
		x = y;
		y = PARENT(y);
	}
	return y;
}



struct Tree *del(struct Tree *T, struct Tree *z)
{
	struct Tree *y = NIL;
	if ((NIL == LEFT(z)) || (NIL == RIGHT(z)))
	{
		y = z;
	}
	else
	{
		y = successor(z);
	}
	struct Tree *x = NIL;
	if (NIL != LEFT(y))
	{
		x = LEFT(y);
	}
	else
	{
		x = RIGHT(y);
	}
	if (NIL != x)
	{
		PARENT(x) = PARENT(y);
	}
	if (NIL == PARENT(y))
	{
		ROOT(T) = x;
	}
	else if (LEFT(PARENT(y)) == y)
	{
		LEFT(PARENT(y)) = x;
	}
	else
	{
		RIGHT(PARENT(y)) = x;
	}
	if (y != z)
	{
		KEY(z) = KEY(y);
	}
	return y;
}


int main()
{
	int flag = 1;
	while (flag)
	{
		printf("\t\t1 creat\n");
		printf("\t\t2 insert\n" );
		printf("\t\t3 search\n");
		printf("\t\t4 delete\n");
		printf("\t\t5 print\n");
		printf("\t\t0 exit\n");
		printf("\t\t:");
		int sel = 0;
		scanf("%d", &sel);
		switch (sel)
		{
			case 1:
				creat(T);
				break;
			case 2:
				{
					int key = 0;
					scanf("%d", &key);
					struct Tree *z = (struct Tree *)malloc(sizeof(struct Tree));
					KEY(z) = key;
					PARENT(z) = NIL;
					LEFT(z) = NIL;
					RIGHT(z) = NIL;
					insert(T, z);
				}
				break;
			case 3:
				{
					int key = 0;
					scanf("%d", &key);
					struct Tree *x = search(ROOT(T), key);
					if (NIL != x)
					{
						printf("success!!\n");
					}
				}break;
			case 4:
				{
					int key = 0;
					scanf("%d", &key);
					struct Tree *x = search(ROOT(T), key);
					if (NIL != x)
					{
						free(x);
						x = NIL;
						printf("delete success!!\n");
					}
					else
					{
						printf("no the key\n");
					}
				}break;
			case 5:
				{
					left_mid_right(ROOT(T));
					printf("\n");
				}break;
			case 0:
				flag = 0;
				break;
			default:
				printf("error!!\n");
		}
	}
	return 0;
}



红黑树:

#include <stdio.h>
#include <stdlib.h>


#define BLACK 0 
#define RED 1 
#define LEFT(_T_)	(_T_->left)
#define RIGHT(_T_)	(_T_->right)
#define PARENT(_T_)	(_T_->parent)
#define COLOR(_T_)	(_T_->color)
#define ROOT(_T_)	(_T_->left)
#define KEY(_T_)	(_T_->key)
#define PNIL	(&NIL)


struct RB_Tree
{
	int key;
	struct RB_Tree *left;
	struct RB_Tree *right;
	struct RB_Tree *parent;
	int color;
};



static struct RB_Tree NIL = {0, NULL, NULL, NULL, BLACK};



void left_mid_right(struct RB_Tree *x)
{
	if (PNIL != x)
	{
		left_mid_right(LEFT(x));
		printf("%d--->", KEY(x));
		left_mid_right(RIGHT(x));
	}
}


struct RB_Tree *search(struct RB_Tree *x, int k)
{
	while ((PNIL != x) && (k != KEY(x)))
	{
		if (KEY(x) < k)
		{
			x = RIGHT(x);
		}
		else
		{
			x = LEFT(x);
		}
	}
	return x;
}


void left_rotation(struct RB_Tree *T, struct RB_Tree *x)
{
	struct RB_Tree *y = RIGHT(x);
	RIGHT(x) = LEFT(y);
	if (PNIL != LEFT(y))
	{
		PARENT(LEFT(y)) = x;
	}
	PARENT(y) = PARENT(x);
	if (PNIL == PARENT(x))
	{
		ROOT(T) = y;
	}
	else if (x == LEFT(PARENT(x)))
	{
		LEFT(PARENT(x)) = y;
	}
	else
	{
		RIGHT(PARENT(x)) = y;
	}
	LEFT(y) = x;
	PARENT(x) = y;
}


void right_rotation(struct RB_Tree *T, struct RB_Tree *x)
{
	struct RB_Tree *y = LEFT(x);
	LEFT(x) = RIGHT(y);
	if (PNIL != RIGHT(y))
	{
		PARENT(RIGHT(y)) = x;
	}
	PARENT(y) = PARENT(x);
	if (PNIL == PARENT(x))
	{
		ROOT(T) = y;
	}
	else if (x == LEFT(PARENT(x)))
	{
		LEFT(PARENT(x)) = y;
	}
	else
	{
		RIGHT(PARENT(x)) = y;
	}
	RIGHT(y) = x;
	PARENT(x) = y;
}


void insert_fixup(struct RB_Tree *T, struct RB_Tree *x)
{
	while (RED == COLOR((PARENT(x))))
	{
		struct RB_Tree *y = PARENT(x);
		if (y == LEFT(PARENT(y)))
		{
			struct RB_Tree *z = RIGHT(PARENT(y));
			if (RED == COLOR(z))
			{
				COLOR(y) = BLACK;
				COLOR(z) = BLACK;
				COLOR(PARENT(y)) = RED;
				x = PARENT(y);
				y = PARENT(x);
			}
			else
			{
				if (x == RIGHT(y))
				{
					x = y; 
					left_rotation(T, x);
				}
				COLOR(y) = BLACK;
				COLOR(PARENT(y)) = RED;
				right_rotation(T, PARENT(y));
			}
		}
		else 
		{
			struct RB_Tree *z = LEFT(PARENT(y));
			if (RED == COLOR(z))
			{
				COLOR(y) = BLACK;
				COLOR(z) = BLACK;
				COLOR(PARENT(y)) = RED;
				x = PARENT(y);
				y = PARENT(x);
			}
			else
			{
				if (x == LEFT(y))
				{
					x = y; 
					right_rotation(T, x);
				}
				COLOR(y) = BLACK;
				COLOR(PARENT(y)) = RED;
				left_rotation(T, PARENT(y));
			}
		}
	}
	COLOR(ROOT(T)) = BLACK;
}

void insert(struct RB_Tree *T, struct RB_Tree *z)
{
	struct RB_Tree *x = ROOT(T);
	struct RB_Tree *y = PNIL;
	while (PNIL != x)
	{
		y = x;
		if (KEY(x) < KEY(z))
		{
			x = RIGHT(x);
		}
		else
		{
			x = LEFT(x);
		}
	}
	PARENT(z) = y;
	if (PNIL == y)
	{
		ROOT(T) = z;
	}
	else if (KEY(y) < KEY(z))
	{
		RIGHT(y) = z;
	}
	else
	{
		LEFT(y) = z;
	}
	COLOR(z) = RED;
	insert_fixup(T, z);
}


void del_fixup(struct RB_Tree *T, struct RB_Tree *x)
{
	while ((ROOT(T) != x) && (BLACK == COLOR(x)))
	{
		if (x == LEFT(PARENT(x)))
		{
			struct RB_Tree *y = RIGHT(PARENT(x));
			if (RED == COLOR(y))
			{
				COLOR(PARENT(x)) = RED;
				COLOR(y) = BLACK;
				left_rotation(T, PARENT(x));
				y = RIGHT(PARENT(x));
			}
			else if ((BLACK == COLOR(y)) && (BLACK == COLOR(LEFT(y)))
					&& (BLACK == COLOR(RIGHT(y))))
			{
				COLOR(y) = RED;
				x = PARENT(x);
				y = RIGHT(PARENT(x));
			}
			else 
			{
				if (BLACK == COLOR(RIGHT(y)))
				{
					COLOR(y) = RED;
					COLOR(LEFT(y)) = BLACK;
					right_rotation(T, y);
				}
				y = RIGHT(PARENT(x));
				COLOR(y) = COLOR(PARENT(x));
				COLOR(PARENT(x)) = BLACK;
				COLOR(RIGHT(y)) = BLACK;
				left_rotation(T, PARENT(x));
				x = ROOT(T);
			}
		}
		else
		{
			struct RB_Tree *y = LEFT(PARENT(x));
			if (RED == COLOR(y))
			{
				COLOR(PARENT(x)) = RED;
				COLOR(y) = BLACK;
				right_rotation(T, PARENT(x));
				y = LEFT(PARENT(x));
			}
			else if ((BLACK == COLOR(y)) && (BLACK == COLOR(LEFT(y)))
					&& (BLACK == COLOR(RIGHT(y))))
			{
				COLOR(y) = RED;
				x = PARENT(x);
				y = LEFT(PARENT(x));
			}
			else 
			{
				if (BLACK == COLOR(LEFT(y)))
				{
					COLOR(y) = RED;
					COLOR(RIGHT(y)) = BLACK;
					left_rotation(T, y);
				}
				y = LEFT(PARENT(x));
				COLOR(y) = COLOR(PARENT(x));
				COLOR(PARENT(x)) = BLACK;
				COLOR(LEFT(y)) = BLACK;
				right_rotation(T, PARENT(x));
				x = ROOT(T);
			}
		}
	}
	COLOR(x) = BLACK;
}


struct RB_Tree *max(struct RB_Tree *x)
{
	while (PNIL != RIGHT(x))
	{
		x = RIGHT(x);
	}
	return x;
}


struct RB_Tree *min(struct RB_Tree *x)
{
	while (PNIL != LEFT(x))
	{
		x = LEFT(x);
	}
	return x;
}


struct RB_Tree *successor(struct RB_Tree *x)
{
	if (PNIL != RIGHT(x))
	{
		return min(RIGHT(x));
	}
	struct RB_Tree *y = PARENT(x);
	while ((PNIL != y) && (x == RIGHT(y)))
	{
		x = y;
		y = PARENT(y);
	}
	return y;
}



struct RB_Tree *del(struct RB_Tree *T, struct RB_Tree *z)
{
	struct RB_Tree *y = PNIL;
	if ((PNIL == LEFT(z)) || (PNIL == RIGHT(z)))
	{
		y = z;
	}
	else
	{
		y = successor(z);
	}
	struct RB_Tree *x = PNIL;
	if (PNIL != LEFT(y))
	{
		x = LEFT(y);
	}
	else
	{
		x = RIGHT(y);
	}
	PARENT(x) = PARENT(y);	
	if (PNIL == PARENT(y))
	{
		ROOT(T) = x;
	}
	else if (y == LEFT(PARENT(y)))
	{
		LEFT(PARENT(y)) = x;
	}
	else
	{
		RIGHT(PARENT(y)) = x;
	}
	if (y != z)
	{
		KEY(z) = KEY(y);
	}
	if (BLACK == COLOR(y))
	{
		del_fixup(T, x);
	}
	return y;
}


struct RB_Tree *creat()
{
	struct RB_Tree *T = (struct RB_Tree *)malloc(sizeof(struct RB_Tree));
	LEFT(T) = PNIL;
	RIGHT(T) = PNIL;
	int key = 0;
	while (EOF != scanf("%d", &key))
	{
		struct RB_Tree *z = (struct RB_Tree *)malloc(sizeof(struct RB_Tree));
		LEFT(z) = PNIL;
		RIGHT(z) = PNIL;
		KEY(z) = key;
		COLOR(z) = RED;
		insert(T, z);
	}
	return T;
}


int main()
{
	struct RB_Tree *T = NULL;
	int flag = 1;
	while (flag)
	{
		printf("\t\t\t1: creat\n");
		printf("\t\t\t2: insert\n");
		printf("\t\t\t3: delete\n");
		printf("\t\t\t4: search\n");
		printf("\t\t\t5: print\n");
		printf("\t\t\t0: exit\n");
		int sel = 0;
		scanf("%d", &sel);
		switch (sel)
		{
			case 1:
				{
					T = creat();
				}break;
			case 2:
				{
					int key = 0;
					printf("insert key:", &key);
					scanf("%d", &key);
					struct RB_Tree *z = (RB_Tree *)malloc(sizeof(struct RB_Tree));
					LEFT(z) = PNIL;
					RIGHT(z) = PNIL;
					COLOR(z) = RED;
					KEY(z) = key;
					COLOR(z) = RED;
					insert(T, z);
				}break;
			case 3:
				{
					int key = 0;
					printf("delete key:");
					scanf("%d", &key);
					struct RB_Tree *x = search(ROOT(T), key); 
					if (PNIL != x)
					{
						x = del(T, x);
						free(x);
						x = NULL;
					}
				}break;
			case 4:
				{
					int key = 0;
					printf("search key:");
					scanf("%d", &key);
					struct RB_Tree *x = search(ROOT(T), key);
					if (PNIL != x)
					{
						printf("success!!\n");
					}
				}break;
			case 5:
				{
					left_mid_right(ROOT(T));
					printf("\n");
				}break;
			case 0:
				{
					flag = 0;
				}break;
			default:
				printf("error!!\n");
		}
	}
	return 0;
}




  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值