二叉平衡树的算法(C语言)

二叉平衡树的算法(C语言)
二叉平衡树是一种特殊的二叉搜索树,其在搜索上的时间复杂度基本上是线性表与二叉树中最小的,因此是一个非常非常重要的知识点,且应用十分广泛。
本文的算法基于二叉搜索树的插入与删除算法演变而来。
另外构造了3个函数,而这三个函数BFInitiate(), RightRotation(), LeftRotation()在本算法中是十分最重要的。
本文采用三重链表,可以从零开始构造二叉平衡树,自动旋转保持树的平衡;又可以删除二叉平衡树的某个节点(包括根节点),删除后也可以自动旋转保持平衡。
也可以采用JAVA语言实现此算法,JAVA代码行数会更少,不过算法是不会变的。
#include<stdio.h>
#include<stdlib.h>
typedef struct btnode {
int key;
int bf;
struct btnode* Lchild, * Rchild, * Father;
}BTNode;
typedef struct btree {
struct btnode* Root;
}BTree;
BTNode* NewNode() {
BTNode* p = (BTNode*)malloc(sizeof(BTNode));
return p;
}
BTNode* NewNode2(int x) {
BTNode* p = (BTNode*)malloc(sizeof(BTNode));
p->key = x;
p->bf = 0;
p->Lchild = NULL;
p->Rchild = NULL;
p->Father = NULL;
return p;
}
void CreateBT(BTree* bt) {
bt->Root = NULL;
}
void MakeBT(BTree* bt, int x, BTree* lt, BTree* rt) {
BTNode* p = NewNode();
p->key = x;
p->Father = NULL;
if (rt->Root != NULL) {
rt->Root->Father = p;
}
p->Rchild = rt->Root;
if (lt->Root != NULL) {
lt->Root->Father = p;
}
p->Lchild = lt->Root;
lt->Root = rt->Root = NULL;
bt->Root = p;
}
void BreakBT(BTree* bt, BTree* lt, BTree* rt) {
BTNode* p = bt->Root;
if § {
lt->Root = p->Lchild;
rt->Root = p->Rchild;
bt->Root = NULL;
free§;
}
}

int Size(BTNode* p) {
int s, s1, s2;
if (!p) {
return 0;
}
else {
s1 = Size(p->Lchild);
s2 = Size(p->Rchild);
s = s1 + s2 + 1;
return s;
}
}
int SizeofBT(BTree bt) {
return Size(bt.Root);
}
int Depth(BTNode* p) {
if (!p) {
return 0;
}
else {
return 1 + max(Depth(p->Lchild), Depth(p->Rchild));
}
}
int DepthofBT(BTree bt) {
return Depth(bt.Root);
}
int CountLeaf(BTNode* p, int count)
{
if (p != NULL)
{
if (p->Lchild == NULL && p->Rchild == NULL) {
count++;
}
count = CountLeaf(p->Lchild, count);
count = CountLeaf(p->Rchild, count);
}
return count;
}
int NumberofLeaf(BTree bt, int count) {
return CountLeaf(bt.Root, count);
}
void LevelOrd(BTree bt) {
BTNode* p;
BTNode* queue[256];
int front = -1, rear = -1;
p = bt.Root;
rear++;
queue[rear] = p;
while (front != rear) {
front++;
p = queue[front];
printf("%d_[%d] “, p->key, p->bf);
if (p->Lchild != NULL) {
rear++;
queue[rear] = p->Lchild;
}
if (p->Rchild != NULL) {
rear++;
queue[rear] = p->Rchild;
}
}
printf(”\n");
}
void BFInitiate(BTree bt) {
BTNode* p;
BTNode* queue[256];
int front = -1, rear = -1;
p = bt.Root;
rear++;
queue[rear] = p;
while (front != rear) {
front++;
p = queue[front];
p->bf = Depth(p->Lchild) - Depth(p->Rchild);
if (p->Lchild != NULL) {
rear++;
queue[rear] = p->Lchild;
}
if (p->Rchild != NULL) {
rear++;
queue[rear] = p->Rchild;
}
}
printf("\n");
}
void LeftRotation(BTNode* s, BTree bt) {
BTNode
r, * u;
r = (BTNode*)malloc(sizeof(BTNode));
u = (BTNode*)malloc(sizeof(BTNode));
r = s->Lchild;
if (r->bf == -1) {
u = r->Rchild;
r->Rchild = u->Lchild;
u->Lchild = r;
s->Lchild = u->Rchild;
u->Rchild = s;
if (s->Father != NULL) {
if (s->Father->Lchild == s) {
s->Father->Lchild = u;
}
if (s->Father->Rchild == s) {
s->Father->Rchild = u;
}
u->Father = s->Father;
s->Father = u;
r->Father = u;
}
else {
u->Father = NULL;
bt->Root = u;
r->Father = u;
s->Father = u;
}
}
else {
s->Lchild = r->Rchild;
r->Rchild = s;
if (s->Father != NULL) {
if (s->Father->Rchild == s) {
s->Father->Rchild = r;
}
if (s->Father->Lchild == s) {
s->Father->Lchild = r;
}
r->Father = s->Father;
s->Father = r;
}
else {
r->Father = NULL;
bt->Root = r;
s->Father = r;
}
}
}
void RightRotation(BTNode* s, BTree* bt) {
BTNode* r, * u;
r = (BTNode*)malloc(sizeof(BTNode));
u = (BTNode*)malloc(sizeof(BTNode));
r = s->Rchild;
if (r->bf == 1) {
u = r->Lchild;
r->Lchild = u->Rchild;
u->Rchild = r;
s->Rchild = u->Lchild;
u->Lchild = s;
if (s->Father != NULL) {
if (s->Father->Lchild == s) {
s->Father->Lchild = u;
}
if (s->Father->Rchild == s) {
s->Father->Rchild = u;
}
u->Father = s->Father;
s->Father = u;
r->Father = u;
}
else {
u->Father = NULL;
bt->Root = u;
r->Father = u;
s->Father = u;
}
}
else {
s->Rchild = r->Lchild;
r->Lchild = s;
if (s->Father != NULL) {
if (s->Father->Rchild == s) {
s->Father->Rchild = r;
}
if (s->Father->Lchild == s) {
s->Father->Lchild = r;
}
r->Father = s->Father;
s->Father = r;
}
else {
r->Father = NULL;
bt->Root = r;
s->Father = r;
}
}
}
void AVListInsert(BTree* bt, int k) {
BTNode* q, * p, * s;
s = (BTNode*)malloc(sizeof(BTNode));
p = bt->Root;
s = p;
while § {
s = p;
if (k < p->key) {
p = p->Lchild;
}
else if (k > p->key) {
p = p->Rchild;
}
else {
printf(“Duplication! \n”);
return;
}
}
q = NewNode2(k);
if (bt->Root) {
if (k < s->key) {
s->Lchild = q;
q->Father = s;
}
if (k > s->key) {
s->Rchild = q;
q->Father = s;
}
}
else {
bt->Root = q;
return;
}
while (1) {
s->bf = Depth(s->Lchild) - Depth(s->Rchild);
if (s->bf < -1 || s->bf>1) {
break;
}
if (s->Father == NULL) {
break;
}
s = s->Father;
}
if (s->Father == NULL && s->bf >= -1 && s->bf <= 1) {
printf("\n二叉树已经平衡,无需再平衡!\n");
}
if (s->bf == 2) {
LeftRotation(s,bt);
}
if (s->bf == -2) {
RightRotation(s, bt);
}
}

void Visit(BTNode* p) {
printf("%d_[%d] ", p->key, p->bf);
}
void PreOrd(void (Visit)(BTNode u), BTNode* t) {
if (t) {
(Visit)(t);
PreOrd(Visit, t->Lchild);
PreOrd(Visit, t->Rchild);
}
}
void InOrd(void (Visit)(BTNode u), BTNode
t) {
if (t) {
InOrd(Visit, t->Lchild);
(Visit)(t);
InOrd(Visit, t->Rchild);
}
}
void PostOrd(void (Visit)(BTNode u), BTNode
t) {
if (t) {
PostOrd(Visit, t->Lchild);
PostOrd(Visit, t->Rchild);
(Visit)(t);
}
}
void PreOrder(BTree
bt, void (Visit)(BTNode u)) {
PreOrd(Visit, bt->Root);
}
void InOrder(BTree* bt, void (Visit)(BTNode u)) {
InOrd(Visit, bt->Root);
}
void PostOrder(BTree* bt, void (Visit)(BTNode u)) {
PostOrd(Visit, bt->Root);
}

void AVLremove(BTree* bt, int k) {
BTNode* c, * r, * s, * p, * q;
q = (BTNode*)malloc(sizeof(BTNode));
p = bt->Root;
while (p && p->key != k) {
q = p;
if (k < p->key) {
p = p->Lchild;
}
else {
p = p->Rchild;
}
}
if (!p) {
printf("\nNo Element with Key k!\n");
return;
}
printf("\nfind the elememt which you want to delete: %d\n", p->key);
if (p->Lchild && p->Rchild) {
s = p->Rchild;
r = p;
while (s->Lchild) {
r = s;
s = s->Lchild;
}
p->key = s->key;
p = s;
q = r;
}
if (p->Lchild) {
c = p->Lchild;
}
else {
c = p->Rchild;
}
if (p == bt->Root) {
bt->Root = c;
}
else if (p == q->Lchild) {
q->Lchild = c;
if (c != NULL) {
c->Father = q;
}
}
else {
q->Rchild = c;
if (c != NULL) {
c->Father = q;
}
}
free§;
printf(“Remove Succeeded!\n”);
BFInitiate(*bt);
printf("%d\n", q->bf);
while (1) {
q->bf = Depth(q->Lchild) - Depth(q->Rchild);
if (q->bf < -1 || q->bf>1) {
break;
}
if (q->Father == NULL) {
break;
}
q = q->Father;
}
if (q->Father == NULL && q->bf >= -1 && q->bf <= 1) {
printf("\n二叉树已经平衡,无需再平衡!\n");
}
if (q->bf == 2) {
LeftRotation(q, bt);
}
if (q->bf == -2) {
RightRotation(q, bt);
}
}

void main() {
BTree* z;
z = (BTree*)malloc(sizeof(BTree));
CreateBT(z);
AVListInsert(z, 100); //从无到有构造二叉平衡树时,根节点一定要最先创建!
BFInitiate(*z);
LevelOrd(*z);
InOrder(z, Visit);
printf("\n");
AVListInsert(z, 50);
BFInitiate(*z);
LevelOrd(*z);
InOrder(z, Visit);
printf("\n");
AVListInsert(z, 200);
BFInitiate(*z);
LevelOrd(*z);
InOrder(z, Visit);
printf("\n");
AVListInsert(z, 150);
BFInitiate(*z);
LevelOrd(*z);
InOrder(z, Visit);
printf("\n");
AVListInsert(z, 400);
BFInitiate(*z);
LevelOrd(*z);
InOrder(z, Visit);
printf("\n");
AVListInsert(z, 800);
BFInitiate(*z);
LevelOrd(*z);
InOrder(z, Visit);
printf("\n");
AVListInsert(z, 125);
BFInitiate(*z);
LevelOrd(*z);
InOrder(z, Visit);
printf("\n");
AVLremove(z, 50);
BFInitiate(*z);
LevelOrd(*z);
InOrder(z, Visit);
printf("\n");
}

猜你喜欢

转载自blog.csdn.net/m0_47472749/article/details/108523282
今日推荐