基于C实现红黑树

目录

main.c

rbtree.h

rbtree.c

queue.h

queue.c


main.c

#include "rbtree.h"

#define SIZE(a)  (sizeof(a) / sizeof (a[0]))

int main()
{
	RBTree* tree = RBTree_create();
	char a[] = { 'b','a','c','d','e'};
	for (int i = 0; i < SIZE(a); i++)
	RBTree_insert(tree, a[i]);

	RBTree_inOrder(tree);
	puts("");
	RBTree_levelOrder(tree);

	return 0;
}

rbtree.h

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

#define RED false
#define BLACK true

typedef char T;

typedef struct TreeNode_s {
	bool color;
	T key;
	struct TreeNode_s* left;
	struct TreeNode_s* right;
	struct TreeNode_s* parent;
}TreeNode;

typedef struct 
{
	TreeNode* root;
}RBTree;

RBTree* RBTree_create();
void RBTree_insert(RBTree* tree, T key);
void rbtree_insert_fixup(RBTree* tree, TreeNode* node);


//先序遍历
void RBTree_preOrder(RBTree* tree);
//中序
void RBTree_inOrder(RBTree* tree);
//后序
void RBTree_postOrder(RBTree* tree);
//层序
void RBTree_levelOrder(RBTree* tree);


//根据先序和中序遍历,构建树
RBTree* RBTree_build(char* preOrder, char* inOrder);

rbtree.c

#include "rbtree.h"
#include "queue.h"

#define parent(x) ((x)->parent)
#define grandParent(x) ((x)->parent->parent)


void rotate_left(RBTree* tree, TreeNode* x)
{
	TreeNode* y = x->right;
	x->right = y->left;

	if (y->left) y->left->parent = x;
	y->parent = x->parent;

	if (x->parent == NULL)tree->root = y;
	else
	{
		if (x->parent->left == x)
			x->parent->left = y;
		else x->parent->right = y;
	}
	y->left = x;
	x->parent = y;
}

void rotate_right(RBTree* tree, TreeNode* x)
{
	TreeNode* y = x->left;
	x->left = y->right;
	if (y->right) y->right->parent = y;
	y->parent = x->parent;

	if (x->parent == NULL) tree->root = y;
	else
	{
		if (x->parent->right == x) x->parent->right = y;
		else x->parent->left = y;
	}
	y->right = x;
	x->parent = y;
}

void rbtree_insert_fixup(RBTree* tree, TreeNode* node)
{
	TreeNode* parent = node->parent;

	while (parent != NULL && parent->color == RED)
	{
		TreeNode* grandParent = parent->parent;

		if (parent == grandParent->left)
		{
			TreeNode* uncle = grandParent->right;
			if (uncle != NULL && uncle->color == RED)
			{
				uncle->color = BLACK;
				parent->color = BLACK;
				grandParent->color = RED;
				node = grandParent;
				continue;
			}
			if (node == parent->right)
			{
				node = parent;
				rotate_left(tree, node);
			}
			grandParent(node)->color = RED;
			parent(node)->color = BLACK;
			rotate_right(tree, grandParent(node));
		}
		else
		{
			TreeNode* uncle = grandParent->left;

			if (uncle != NULL && uncle->color == RED)
			{
				uncle->color = BLACK;
				parent->color = BLACK;
				grandParent->color = RED;
				node = grandParent;
				continue;
			}
			if (node == parent->left)
			{
				node = parent;
				rotate_right(tree, grandParent(node));
			}
			grandParent(node)->color = RED;
			parent(node)->color = BLACK;
			rotate_left(tree, grandParent(node));
		}
	}
	tree->root->color = BLACK;
}




RBTree* RBTree_create()
{
	return (RBTree*)calloc(1, sizeof(RBTree));
}
void RBTree_insert(RBTree* tree, T key)
{
	TreeNode* pre = NULL;
	TreeNode *now = tree->root;

	while (now != NULL)
	{
		pre = now;
		int t = key - now->key;
		if (t < 0) now = now->left;
		//当前节点的值大于要插入的值
		else if (t > 0) now = now->right;
		else return; // 找到相等的值不用创建
	} 
	// 找到了要插入的位置,创建新节点

	TreeNode* node = (TreeNode*)calloc(1, sizeof(TreeNode));
	if (node == NULL)
	{
		printf("Error:malloc failed in RBTree_insert\n");
		exit(1);
	}
	node->key = key;
	//插入节点
	node->parent = pre;
// 判断插入的结点  与前一个节点的位置关系	 
	if (pre == NULL)// 插入的结点是第一个
		tree->root = node;
	else if (key < pre->key)
		pre->left = node;
	else
		pre->right = node;
	rbtree_insert_fixup(tree, node);
}
//先序遍历
void preOrder(TreeNode* root)
{
	if (root == NULL) return;
	printf("%c ", root->key);
	preOrder(root->left);
	preOrder(root->right);
}
void RBTree_preOrder(RBTree* tree)
{
	preOrder(tree->root);
}
//中序
void inOrder(TreeNode* root)
{
	//边界条件 
	if (root == NULL) return;
	// 遍历左子树
	inOrder(root->left);
	// 遍历根节点
	printf("%c ", root->key);
	// 遍历右子树
	inOrder(root->right);
}
void RBTree_inOrder(RBTree* tree)
{
	//委托这个方法实现
	inOrder(tree->root);
}
//后序
void postOrder(TreeNode* root)
{
	if (root == NULL) return;
	postOrder(root->left);
	postOrder(root->right);
	printf("%c ", root->key);
}

void RBTree_postOrder(RBTree* tree)
{
	postOrder(tree->root);
}

//层序
void RBTree_levelOrder(RBTree* tree)
{
	if (tree->root == NULL)return;
	queue* q = queue_create();
	//将根节点入队列
	enqueue(q, tree->root);

	while (!isEmpty(q))
	{
		TreeNode* node =  dequeue(q);
		printf("%c ", node->key);
		if (node->left != NULL)enqueue(q, node->left);
		if (node->right != NULL)enqueue(q, node->right);

	}

}
//根据先序和中序遍历,构建树
//创建所有节点,并把根节点赋值给TreeNode 
TreeNode* PreInBuild(char* preOrder, char* inOrder,int len)
{
	if (len == 0) return NULL ;
	char  ch = *preOrder;
	//构建根节点
	TreeNode* root = (TreeNode*)calloc(1, sizeof(TreeNode));
	root->key = ch;
	int idx = 0; 
	// 找到根节点在中序遍历的位置
	for (; idx < len; idx++)
	{
		if (inOrder[idx] == ch)break;
	} 
// inOrder
// [0,idx-1] idx [idx+1,len-1]
	//构建左子树
	root->left = PreInBuild(preOrder+1,inOrder,idx);
	//构建右子树
	root->right = PreInBuild(preOrder + 1 + idx, inOrder + idx + 1, len - idx -1 );
	return root;
}
RBTree* PreInRBTree_build(char* preOrder, char* inOrder,int len)
{
	RBTree* tree = (RBTree*)calloc(1, sizeof(RBTree));
	tree->root = PreInBuild(preOrder,inOrder,len );
	return tree;
}


//知道中序遍历和后序遍历构建树
TreeNode* InPostBuild(char* inOrder, char* postOrder, int len)
{
	if (len == 0) return NULL;
	char ch = *(postOrder + len - 1);

	TreeNode* root = (TreeNode*)calloc(1, sizeof(TreeNode));
	root->key = ch;
	int idx = 0;
	while (inOrder[idx] != ch) idx++;

	root->left = InPostBuild(inOrder, postOrder, idx);
	root->right = InPostBuild(inOrder + idx + 1, postOrder + idx, len - idx - 1);
	return root;
}


RBTree* InPostRBTree_build(char* inOrder, char* postOrder, int len)
{
	RBTree* tree = (RBTree*)calloc(1, sizeof(RBTree));
	tree->root = InPostBuild(inOrder, postOrder, len);
	return tree;
}




queue.h

#pragma once 
#include <stdlib.h>
#include <stdbool.h>
#include <stdio.h>
#define N 25
typedef struct TreeNode_s TreeNode;
typedef struct {
	TreeNode* elements[N]; 
	int front;
	int end;
}queue;

//创建空的队列
queue* queue_create();

void queue_destory(queue* q);

void enqueue(queue *q, TreeNode* val);//入队
TreeNode* dequeue(queue* q); // 出队
TreeNode* peek(queue* q);
bool isEmpty(queue* q);
bool isFull(queue* q);

queue.c

#include "queue.h"


queue* queue_create()
{
	return (queue*)calloc(1, sizeof(queue));
}
void queue_destory(queue* q)
{
	free(q);
}

void enqueue(queue* q, TreeNode* val)
{
	if (isFull(q))
	{
		printf("Error:queue is Full \n"); exit(1);
	}
	q->elements[q->end] = val;
	q->end = (q->end + 1 ) % N ; // 更新end的值
}
TreeNode* dequeue(queue* q) // 出队
{
	if (isEmpty(q))
	{
		printf("Error : queue is Empty!\n");
		exit(1);
	}
	TreeNode* t = q->elements[q->front];
	q->front = (q->front + 1) % N;
	return t;

}
TreeNode* peek(queue* q)
{
	if (isEmpty(q))
	{
		printf("Error : queue is Empty\n"); exit(1);
	}
	return q->elements[q->front];
}
bool isEmpty(queue* q)
{
	return q->front == q->end;
}
bool isFull(queue* q)
{
	return q->front == (q->end + 1) % N;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值