二叉树与红黑树
二叉排序树
二叉排序树性质:
一棵空树,或者是具有下列性质的二叉树:
(1)若左子树不空,则左子树上所有结点的值均小于它的根结点的值;
(2)若右子树不空,则右子树上所有结点的值均大于它的根结点的值;
(3)左、右子树也分别为二叉排序树;
(4)没有键值相等的结点。
二叉树,实现了 插入、删除功能。删除功能代码感觉韧性不够。仍然缺少整体构建思维,比如,在写该功能模块之前,应分析该删除的节点的子节点分类情形:
- 0个子节点、
- 1个子节点
- 2个子节点。
按照这个思路写代码,会比较顺。
#include <stdlib.h>
#include <stdio.h>
#define KEY_VALUE int
#define BSTREE_ENTRY(name ,type) \
struct name{ \
struct type *left; \
struct type *right; \
}
//二叉树节点
struct bstree_node {
KEY_VALUE data;
BSTREE_ENTRY(,bstree_node)bst;
};
//二叉树根节点
struct bstree {
struct bstree_node *root;
};
//创造节点
struct bstree_node * _bstree_create_node(KEY_VALUE value)
{
struct bstree_node *node = (struct bstree_node *)malloc(sizeof(struct bstree_node));
if (node == NULL) {
printf("malloc error!\n");
return NULL;
}
node->data = value;
node->bst.left = node->bst.right = NULL;
return node;
}
//插入节点
int bstree_insert(struct bstree *T, KEY_VALUE data)
{
if (T->root == NULL) {
T->root = _bstree_create_node(data);
return 0;
}
struct bstree_node *temp = T->root;
struct bstree_node *node = T->root;
while (temp != NULL) {
node = temp;
if (data > temp->data) {
temp = temp->bst.right;
} else if (data < temp->data) {
temp = temp->bst.left;
} else {
printf("data already exist!\n");
return -1;
}
}
if (data > node->data) {
node->bst.right = _bstree_create_node(data);
} else {
node->bst.left = _bstree_create_node(data);
}
return 0;
}
void bstree_successor(struct bstree *T, struct bstree_node *x) {
struct bstree_node *node = x;
struct bstree_node *temp = x;
while (temp->bst.left != NULL) {
node = temp;
temp = temp->bst.left;
}
T->root->data = temp->data;
if (temp == T->root->bst.right) {
T->root->bst.right = temp->bst.right;
free(temp);
return;
}
node->bst.left = NULL;
free(temp);
}
void bstree_successor_node(struct bstree_node *T, struct bstree_node *x)
{
struct bstree_node *node = T;
struct bstree_node *temp = x;
while (temp->bst.left != NULL) {
node = temp;
temp = temp->bst.left;
}
T->data = temp->data;
if (temp == T->bst.right) {
free(T->bst.right);
T->bst.right = NULL;
return;
}
node->bst.left = NULL;
free(temp);
}
//删除节点
/*
1. 删除的是根节点
2. 删除的不是根节点
采用交换的方法 将待“删除”节点的后继的值放入“删除“节点中,然后删除后继节点。
*/
int bstree_delete(struct bstree *T, KEY_VALUE data)
{
struct bstree_node *temp = T->root;
struct bstree_node *node = T->root;
while(temp != NULL) {
if (data == temp->data) {
if(temp == T->root){
if (temp->bst.right == NULL) {
T->root = temp->bst.left;
free(temp);
return 0;
} else {
bstree_successor(T, temp->bst.right);
}
} else {
if (temp->bst.right == NULL) {
if (temp == node->bst.right) {
node->bst.right = temp->bst.left;
free(temp);
} else {
node->bst.left = temp->bst.left;
free(temp);
}
} else {
bstree_successor_node(temp, temp->bst.right);
}
}
return 0;
} else if (data > temp->data) {
node = temp;
temp = temp->bst.right;
} else {
node = temp;
temp = temp->bst.left;
}
}
printf("no node!\n");
return -1;
}
void bstree_traversal(struct bstree_node *node) {
if (node ==NULL) return ;
bstree_traversal(node->bst.left);
printf("%4d", node->data);
bstree_traversal(node->bst.right);
}
int main(int argc, char* argv[])
{
struct bstree T;
int buf[20] = {32,52,13,53,23, 26,77,46,37,98, 20,13,17,48,10, 19,9,24,14,16};
int i;
for(i=0; i<20; i++){
bstree_insert(&T, buf[i]);
}
bstree_traversal(T.root);
putchar('\n');
}
红黑树,还没有搞明白,待搞明白后,在编写代码。