C++标准模板库(STL)之set 容器底层实现--C语言实现(二叉平衡树)

C++标准模板库(STL)中有一个很重要的容器是set 容器,它的底层实现其实是二叉树,具体来说应该是二叉平衡树,这是一种在内存中十分高效的可自动排序的存储容器。
该容器的成员函数在插入元素的时候可以自动排序,而且可以按照值搜索元素与删除或者替换元素。
本文以数据结构中的二叉平衡树入手,从底层重现C++标准模板库set 容器的各项函数,以及补充了另外一些函数,包括树的各种遍历方式,以及统计二叉平衡树的高度,叶子节点数量等等。
二叉平衡树是一种特殊的二叉搜索树,其在搜索上的时间复杂度基本上是线性表与二叉树中最小的,因此是一个非常非常重要的知识点,且应用十分广泛。
本文的算法基于二叉搜索树的插入与删除算法演变而来。
另外构造了3个函数,而这三个函数BFInitiate(), RightRotation(), LeftRotation()在本算法中是十分最重要的。
本文采用三重链表,可以从零开始构造二叉平衡树,自动旋转保持树的平衡;又可以删除二叉平衡树的某个节点(包括根节点),删除后也可以自动旋转保持平衡。

#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 (p) {
    
    
		lt->Root = p->Lchild;
		rt->Root = p->Rchild;
		bt->Root = NULL;
		free(p);
	}
}

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 AVListInsert(BTree* bt, int k) {
    
    
	BTNode* q, * p, * s, * u, * r;
	s = (BTNode*)malloc(sizeof(BTNode));
	r = (BTNode*)malloc(sizeof(BTNode));
	u = (BTNode*)malloc(sizeof(BTNode));
	p = bt->Root;
	s = p;
	while (p) {
    
    
		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) {
    
    
		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;
			}
		}
	}
	if (s->bf == -2) {
    
    
		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 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, *m, *u;
	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(p);
	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) {
    
    
		m = q->Rchild;
		if (m->bf == 1) {
    
    
			u = m->Lchild;
			m->Lchild = u->Rchild;
			u->Rchild = m;
			q->Rchild = u->Lchild;
			u->Lchild = q;
			if (q->Father != NULL) {
    
    
				if (q->Father->Lchild == q) {
    
    
					q->Father->Lchild = u;
				}
				if (q->Father->Rchild == q) {
    
    
					q->Father->Rchild = u;
				}
				u->Father = q->Father;
				q->Father = u;
				m->Father = u;
			}
			else {
    
    
				u->Father = NULL;
				bt->Root = u;
				m->Father = u;
				q->Father = u;
			}
		}
		else {
    
    
			q->Rchild = m->Lchild;
			m->Lchild = q;
			if (q->Father != NULL) {
    
    
				if (q->Father->Rchild == q) {
    
    
					q->Father->Rchild = m;
				}
				if (q->Father->Lchild == q) {
    
    
					q->Father->Lchild = m;
				}
				m->Father = q->Father;
				q->Father = m;
			}
			else {
    
    
				m->Father = NULL;
				bt->Root = m;
				q->Father = m;
			}
		}
	}
	if (q->bf == 2) {
    
    
		m = q->Lchild;
		if (m->bf == -1) {
    
    
			u = m->Rchild;
			m->Rchild = u->Lchild;
			u->Lchild = m;
			q->Lchild = u->Rchild;
			u->Rchild = q;
			if (q->Father != NULL) {
    
    
				if (q->Father->Lchild == q) {
    
    
					q->Father->Lchild = u;
				}
				if (q->Father->Rchild == q) {
    
    
					q->Father->Rchild = u;
				}
				u->Father = q->Father;
				q->Father = u;
				m->Father = u;
			}
			else {
    
    
				u->Father = NULL;
				bt->Root = u;
				m->Father = u;
				q->Father = u;
			}
		}
		else {
    
    
			q->Lchild = m->Rchild;
			m->Rchild = q;
			if (q->Father != NULL) {
    
    
				if (q->Father->Rchild == q) {
    
    
					q->Father->Rchild = m;
				}
				if (q->Father->Lchild == q) {
    
    
					q->Father->Lchild = m;
				}
				m->Father = q->Father;
				q->Father = m;
			}
			else {
    
    
				m->Father = NULL;
				bt->Root = m;
				q->Father = m;
			}
		}
	}
}

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");
	AVLremove(z, 150);
	BFInitiate(*z);
	LevelOrd(*z);
	InOrder(z, Visit);
	printf("\n");
}

猜你喜欢

转载自blog.csdn.net/m0_47472749/article/details/111144377