c語言 每週一練 平衡二叉樹

2022-03-27 13:08:34 字數 3391 閱讀 5054

平衡二叉樹是這樣一棵樹:它是一棵空樹或它的左右兩個子樹的高度差的絕對值不超過1,並且左右兩個子樹都是一棵平衡二叉樹。查詢、插入和刪除在平均和最壞情況下都是o(log n)。可以用於資料庫設計,記憶體分配演算法等。

/*

平衡二叉查詢樹

written by huals

2012.10.13

*/#include

#include

typedef

struct

bstreenode bstreenode;

typedef

struct

bstree bstree;

void bstree_init(bstree *tree);

void bstreenode_init(bstreenode *z,int

value);

void insert_bstree(bstree *t,bstreenode *z);

void left_rotate(bstree *t,bstreenode *z);

void right_rotate(bstree *t,bstreenode *z);

void delete_node(bstree *t,bstreenode *z);

bstreenode* next_node(bstree *t,bstreenode *z);

bstreenode* pre_node(bstree *t,bstreenode *z);

bstreenode* search_node(bstree *t,int

value);

void modify_len(bstree *t,bstreenode *x);

void balance_tree(bstree *t,bstreenode *y);

void print_tree(bstree *t);

void print_value(bstreenode *z);

void print_info_tree(bstree *t);

int main(void)//

刪除第十個節點,輸出

//delete_node(tree,search_node(tree,4));

print_info_tree(tree);

print_tree(tree);}//

樹初始化

void bstree_init(bstree *tree)

//節點初始化

void bstreenode_init(bstreenode *z,int

value)

//插入節點,ok

void insert_bstree(bstree *t,bstreenode *z)

z->parent=x;

if(x==null)

t->root=z;

else

//更新插入節點到根節點的len值

y=z;

while(y->parent!=null && y->len+1>y->parent->len)

//調整二叉樹使平衡

balance_tree(t,z);

t->node_number++;}//

左旋void left_rotate(bstree *t,bstreenode *z)

z->parent=x;

x->left=z;

//手動更新調整變換的關鍵點的len

llen=(z->left==null?0:z->left->len+1

);rlen=(z->right==null?0:z->right->len+1

);z->len=(llen>=rlen?llen:rlen);

llen=z->len+1

;rlen=(x->right==null?0:x->right->len+1

);x->len=(llen>=rlen?llen:rlen);

//除錯用:輸出調整節點的值

//printf("z is %d,z len is %d\n",z->value,z->len);

//更新因旋轉後造成len的變化

modify_len(t,x);}//

右旋void right_rotate(bstree *t,bstreenode *z)

x->right=z;

z->parent=x;

//更新len

llen=(z->left==null?0:z->left->len);

rlen=(z->right==null?0:z->right->len);

z->len=(llen>=rlen?llen+1:rlen+1

);llen=z->len+1

;rlen=(x->left==null?0:x->left->len+1

);x->len=(llen>=rlen?llen:rlen);

modify_len(t,z);}//

搜尋後繼節點

bstreenode* next_node(bstree *t,bstreenode *z)

if(y==null)

returny;}

//搜尋前仆節點

bstreenode* pre_node(bstree *t,bstreenode *z)

if(y==null)

returny;}

//搜尋指定關鍵字節點,返回節點指標

bstreenode* search_node(bstree *t,int

value)

returnx;}

//輸出樹的節點及其len值

void print_tree(bstree *t)

//輸出樹的資訊:根節點及節點數目

void print_info_tree(bstree *t)

//遞迴輸出節點值及len值

void print_value(bstreenode *z)

//刪除節點

void delete_node(bstree *t,bstreenode *z)

if(y!=z)

x=y->parent;

if(x!=null)}/*

旋轉節點和刪除節點時會造成節點len值動盪,而x則是動盪的那一支,x本身len值正確,只是x父節點,祖先節點未知,需要調整

ok*/

void modify_len(bstree *t,bstreenode *x)}//

沿著y想根節點方向搜尋不平衡節點,並通過旋轉調整

void balance_tree(bstree *t,bstreenode *y)

y=y->parent;}//

旋轉時需要判斷是否需要兩次旋轉

if(flag==1)}

if(flag==2

)else

}}

平衡二叉樹例題 平衡二叉樹

acwing 72.平衡二叉樹 思路一 求每個節點的左右子樹深度,根據深度差判斷,直到葉子節點結束,效率不夠高,每個節點都要用兩次計算深度的遞迴函式 思路二 從葉子節點開始,計算深度差,一旦有深度差大於1的,就直接返回0,也不用管上面的深度是不是正確了,畢竟我們只需要true和false兩種狀態,省...

每日一練之二叉樹的深度

方法一 遞迴void treedepthhelper treenode proot,int curr,int max return treedepthhelper proot left,curr 1,max treedepthhelper proot right,curr 1,max inttree...

每日一練(15) 二叉樹的映象

title 每日一練 15 二叉樹的映象 categories 劍指offer tags 每日一練 date 2022 01 28 請完成乙個函式,輸入乙個二叉樹,該函式輸出它的映象。例如輸入 4 2 7 1 3 6 9映象輸出 4 7 2 9 6 3 1示例 1 輸入 root 4,2,7,1,3...