二叉平衡树,大神帮忙找找虫子
最新想弄个动态属性保存的二叉树结构,想网上移植个标准c红黑树实现,结果都没成功。自己实现红黑树都要晕了,情况判断太多了,还费力不讨好。由于我对插入属性速度要求低就想自己实现个简单的平衡树
思路就是在树节点中维护 左深度ld 和 右深度rd 两个属性来调整树的平衡
当ld和rd的差值大于2就对该节点进行左旋或右旋操作(为什么是大于二呢?就是左右旋转操作的最小深度都达到了2,小2就矛盾了)
因此插入删除操作的时间复杂度就会是O(2lg(n)),查询操作的复杂度为O(lg(n)+2)
自己测了好多数据,也没发现问题,大家帮忙测测,有问题提一下,谢谢了
下面就上代码了
ztl_tree.h
程序代码:
#include <stdio.h>
#include <stddef.h>
#include <stdlib.h>
typedef unsigned char byte;
typedef struct ztl_tree_node ztl_tree_node_t;
typedef ztl_tree_node_t* ztl_tree_node_p;
struct ztl_tree_node{
unsigned long k;
size_t v;
ztl_tree_node_p l;
ztl_tree_node_p r;
ztl_tree_node_p p;
byte ld;
byte rd;
};
typedef struct ztl_tree ztl_tree_t;
typedef ztl_tree_t* ztl_tree_p;
struct ztl_tree{
int size;
ztl_tree_node_p root;
};
ztl_tree_p ztl_tree_init();
void ztl_tree_deep(ztl_tree_p tree, ztl_tree_node_p node);
void ztl_tree_adjust(ztl_tree_p tree, ztl_tree_node_p node);
void ztl_tree_add(ztl_tree_p tree, unsigned long key, size_t value);
ztl_tree_node_p ztl_tree_behind_node(ztl_tree_p tree, ztl_tree_node_p node);
size_t ztl_tree_remove(ztl_tree_p tree, unsigned long key);
ztl_tree_node_p ztl_tree_get_node(ztl_tree_p tree, unsigned long key);
size_t ztl_tree_get(ztl_tree_p tree, unsigned long key);
void ztl_tree_iterate(ztl_tree_p tree, ztl_tree_node_p node);
void ztl_tree_destory_it(ztl_tree_p tree, ztl_tree_node_p node);
void ztl_tree_destory(ztl_tree_p tree);
/** fun impl **/
ztl_tree_p ztl_tree_init()
{
ztl_tree_p tree = calloc(1,sizeof(ztl_tree_t));
tree->size=0;
tree->root=0;
return tree;
}
/**节点深度值维护*/
void ztl_tree_deep(ztl_tree_p tree, ztl_tree_node_p node)
{
if(!node)return;
if(node->l){
byte mxd = node->l->ld > node->l->rd ? node->l->ld : node->l->rd;
node->ld = mxd+1;
}else{
node->ld = 0;
}
if(node->r){
byte mxd = node->r->ld > node->r->rd ? node->r->ld : node->r->rd;
node->rd = mxd+1;
}else{
node->rd = 0;
}
}
/**节点调整*/
void ztl_tree_adjust(ztl_tree_p tree, ztl_tree_node_p node)
{ //printf("ztl_tree_adjust.......\n");
if(!node)return;
ztl_tree_deep(tree, node);
int dif = node->ld - node->rd;
if(dif > 2){//右旋
if(node->p){
if(node == node->p->l){
node->p->l = node->l;
}else{
node->p->r = node->l;
}
node->l->p = node->p;
}else{
node->l->p = 0;
tree->root = node->l;
}
ztl_tree_node_p nlr = node->l->r;
node->l->r = node;
node->p = node->l;
node->l = nlr;
if(nlr) nlr->p = node;
ztl_tree_deep(tree, node);
ztl_tree_deep(tree, node->p);
node = node->p;
}else if(dif < -2){//左旋
if(node->p){
if(node == node->p->l){
node->p->l = node->r;
}else{
node->p->r = node->r;
}
node->r->p = node->p;
}else{
node->r->p = 0;
tree->root = node->r;
}
ztl_tree_node_p nrl = node->r->l;
node->r->l = node;
node->p = node->r;
node->r = nrl;
if(nrl)nrl->p = node;
ztl_tree_deep(tree, node);
ztl_tree_deep(tree, node->p);
node = node->p;
}
ztl_tree_adjust(tree, node->p);
}
void ztl_tree_add(ztl_tree_p tree, unsigned long key, size_t value)
{
ztl_tree_node_p nnod = calloc(1, sizeof(ztl_tree_node_t));
nnod->k = key;
nnod->v = value;
if(tree->root){ //printf("11111111111.......start \n");
ztl_tree_node_p node = tree->root;
while(node){
if(key < node->k){
if(node->l){
node = node->l;
}else{
node->l = nnod;
nnod->p = node;
ztl_tree_adjust(tree, nnod);
tree->size++;
return;
}
}else if(key > node->k){
if(node->r){
node = node->r;
}else{
node->r = nnod;
nnod->p = node;
ztl_tree_adjust(tree, nnod);
tree->size++;
return;
}
}else{
node->v = value;
return;
}
}
//printf("11111111111.......end\n");
}else{ //printf("222222222.......start\n");
tree->root = nnod;
tree->size = 1;
}
}
/**后继节点*/
ztl_tree_node_p ztl_tree_behind_node(ztl_tree_p tree, ztl_tree_node_p node){
if(!node) return 0;
ztl_tree_node_p cnod = node->r;
while(cnod){
if(cnod->l)cnod = cnod->l;
else break;
}
return cnod;
}
size_t ztl_tree_remove(ztl_tree_p tree, unsigned long key)
{
ztl_tree_node_p node = ztl_tree_get_node(tree, key);
if(!node) return -1;
ztl_tree_node_p bnod = ztl_tree_behind_node(tree, node);
if(bnod){//删除节点有右分支
ztl_tree_node_p bpnod = bnod->p;
//父关系维护
if(node->p){
if(node == node->p->l){
node->p->l = bnod;
}else{
node->p->r = bnod;
}
bnod->p = node->p;
}else{
bnod->p = 0;
tree->root = bnod;
}
//左边关系维护
bnod->l = node->l;
if(node->l)node->l->p = bnod;
//右边关系维护
if(bnod != node->r){//后继节点不等于右节点
bnod ->r = node->r;
node->r->p = bnod;
bpnod->l = 0;//后继节点父关系(后继结点必是左节点)
ztl_tree_adjust(tree, bpnod);
}else{//后继节点等于右节点(不需要维护右边的关系)
ztl_tree_adjust(tree, node->r);
}
}else{//删除节点没有右分支
if(node->l){//删除节点没有右分支,但有左分支
if(node->p){
if(node == node->p->l){
node->p->l = node->l;
}else{
node->p->r = node->l;
}
node->l->p = node->p;
}else{
node->l->p = 0;
tree->root = node->l;
}
ztl_tree_adjust(tree, node->l);
}else{//删除节点没有左右分支
if(node->p){
if(node == node->p->l){
node->p->l = 0;
}else{
node->p->r = 0;
}
ztl_tree_adjust(tree, node->p);
}else{
tree->root = 0;
}
}
}
size_t nv = node->v;
free(node);
tree->size--;
return nv;
}
void ztl_tree_iterate(ztl_tree_p tree, ztl_tree_node_p node)
{
if(node){
printf("key: %d, value: %d, deep: %d, %d\n", (int)node->k, (int)node->v, node->ld, node->rd);
ztl_tree_iterate(tree, node->l);
ztl_tree_iterate(tree, node->r);
}
}
int get_num = 0;
ztl_tree_node_p ztl_tree_get_node(ztl_tree_p tree, unsigned long key)
{
ztl_tree_node_p node = 0;
if(tree->root){
node = tree->root;
while(node){get_num++;
if(key < node->k){
if(node->l){
node = node->l;
}else{
node = 0;
}
}else if(key > node->k){
if(node->r){
node = node->r;
}else{
node = 0;
}
}else{
break;
}
}
}
return node;
}
size_t ztl_tree_get(ztl_tree_p tree, unsigned long key){
ztl_tree_node_p node = ztl_tree_get_node(tree, key);
if(node) return node->v;
return -1;
}
void ztl_tree_destory_it(ztl_tree_p tree, ztl_tree_node_p node)
{
if(node){
ztl_tree_destory_it(tree, node->l);
ztl_tree_destory_it(tree, node->r);
free(node);
}
}
void ztl_tree_destory(ztl_tree_p tree)
{
ztl_tree_destory_it(tree, tree->root);
free(tree);
}
main.c
程序代码:
#include "ztl_tree.h"
int main(int argc, char ** argv)
{
// int a[] = {10, 40, 30, 60, 90, 70, 20, 50, 80, 110,
// 11, 41, 31, 61, 91, 71, 21, 51, 81, 111,
// 12, 42, 32, 62, 92, 72, 22, 52, 82, 112,
// 13, 43, 33, 63, 93, 73, 23, 53, 83, 113,
// 14, 44, 34, 64, 94, 74, 24, 54, 84, 114
// 15, 45, 35, 65, 95, 75, 25, 55, 85, 115,
// 16, 46, 36, 66, 96, 76, 26, 56, 86, 116,
// 17, 47, 37, 67, 97, 77, 27, 57, 87, 117,
// 18, 48, 38, 68, 98, 78, 28, 58, 88, 118,
// 19, 49, 39, 69, 99, 79, 29, 59, 89, 119
// };
ztl_tree_p tree = ztl_tree_init();
for(int i=0; i<2; i++){
//printf("add to tree... %d\n", i);
// ztl_tree_add(tree, a[i], i);
ztl_tree_add(tree, i, i+1);
// ztl_tree_add(tree, rand()%200, i);
}
//ztl_tree_add(tree, 17, 999);
printf("tree Size: %d \n", tree->size);
// ztl_tree_iterate(tree, tree->root);
int dv = ztl_tree_remove(tree, 1);
printf("tree Size: %d, deleteVal: %d, treeRoot:%d \n", tree->size, dv, (int)tree->root);
int maxnum = 0;
for(int i=0; i<3; i++){
get_num = 0;
int gv = ztl_tree_get(tree, i);
maxnum = get_num>maxnum?get_num:maxnum;
printf("get Num: %d, value: %d \n", get_num, gv);
}
printf("\nmaxnum: %d\n", maxnum);
ztl_tree_destory(tree);
return 0;
}










