二叉树的遍历

前序遍历(动态写法、静态写法)

//中序 后序同理

void preorder(bintree bt)
{
	if(bt){
		printf("%d",bt->data);
		preorder(bt->left);
		preorder(bt->right);
	}	
}	
void preorder(int root)
{
	if(root!=-1){
		printf("%d",tree[root].data);
		preorder(tree[root].left);
		preorder(tree[root].right);
	}	
}

层序遍历(动态写法、静态写法)

void levelorder(bintree bt){
	bintree A;
	queue<bintree>qu;
	qu.push(bt);
	while(qu.empty()!=true){
		A = qu.front();
		printf("%d ",A->data);
		qu.pop();
		if(A->lchild) qu.push(A->lchild);
		if(A->rchild) qu.push(A->rchild);
	}
}
void levelorder(int root){
	queue<int>qu;
	qu.push(root);
	int node;
	while(qu.empty()!=true){
		node = qu.front();
		printf("%d ",node);
		qu.pop();
		if(tree[node].left!=-1) qu.push(tree[node].left);
		if(tree[node].right!=-1) qu.push(tree[node].right);
	}
}

前序遍历中序遍历或者后序遍历中序遍历的结果建树

第一步 先用数组把中序遍历和后序遍历或者前序遍历的结果存到数组中

int post[maxn],in[maxn],pre[maxn];

第二步 建树

bintree create(int postl,int postr,int inl,int inr)
{
	if(postl>postr) return NULL;
	bintree bt = (bintree)malloc(sizeof(struct node));
	int root = post[postr];
	bt->data = root;
	int k;
	for(k=inl;k<=inr;k++){
		if(in[k]==root) break;
	}
	int numl = k - inl;
	bt->left = create(postl,postl+numl-1,inl,inl+numl-1);
	bt->right = create(postl+numl,postr-1,inl+numl+1,inr);
	return bt;
}

使用堆栈输出二叉树的序列

按照堆栈输入中序遍历二叉树的顺序 我们可以得到前序序列和中序序列所以可以构建二叉树
比如
Push 1
Push 2
Push 3
Pop
Pop
Push 4
Pop
Pop
Push 5
Push 6
Pop
Pop

前序序列 即push的顺序 1 2 3 4 5 6
中序序列 即pop的顺序 3 2 4 1 6 5

**

求二叉树的高度

**

void postorder(bintree bt){
	if(bt){
		HL = postorder(bt->left);
		HR = postorder(bt->right);
		max = HL>HR?HL:HR;
		return max+1;
	}else{
		return 0;
	}
}

二叉搜索树(BST)

也称二叉排序树 二叉查找树

查找元素值操作

尾递归:程序返回时实现的递归 效率不高可以用循环来替代 
bintree Find(int x,bintree bt)
{
	if(!bt) return NULL;
	else{
		if(bt->data<x) return Find(x,bt->right);
		else if(bt->data>x) return  Find(x,bt->left);
		else return bt;
	}
} 
bintree Find(int x,bintree bt)
{
	while(bt){
		if(bt->data==x) return bt;
		else if(bt->data>x) bt = bt->left;
		else bt = bt->right;
	}
	return NULL;

查找最大值

bintree FindMax(bintree bst)
{
	if(bst){
		while(bst->right){
			bst = bst->right;
		}
		return bst;
	}
} 

查找最小值

bintree FindMin(bintree bt)
{
	if(bst){
		while(bst->left){
			bst = bst->left;
		}
		return bst;
	}
}

插入元素

bintree insert(bintree bst,int x)
{
	if(!bst){
		bst = (bintree)malloc(sizeof(struct node));
		bst->data = x;
		bst->left = bst->right = NULL;
	}
	else{
		if(bst->data>x) bst->left = insert(bst->left,x);
		else if(bst->data<x) bst->right = insert(bst->right,x);
	}
	return bst;
}

删除元素

bintree Delete(bintree bst,int x)
{
	bintree tmp;
	if(!bst) printf("not found");
	else if(bst->data>x) bst->left = Delete(bst->left,x);
	else if(bst->data<x) bst->right = Delete(bst->right,x);
	else{
		if(bst->left&&bst->right){
			tmp = FindMin(bst->right);
			bst->data = tmp->data;
			bst->right = Delete(bst->right,bst->data);
		}else{
			tmp = bst;
			if(!bst->left) bst = bst->right;
			else if(!bst->right) bst = bst->left;
			free(tmp);
		}
	}
	return bst;
}

平衡二叉树(AVL)

任一结点左右子树的高度差不超过1

**一般的二叉搜索树在插入元素后复杂度容易变成O(N),AVL树保证插入操作后树的高度在每次插入后仍然可以保持O(logn)的级别。
**

结构

struct node{
	struct node*left;
	struct node*right;
	int height;
	int data;
};
typedef struct node* AVLTree;

树的高度

int getheight(AVLTree T)
{
	if(T==NULL) return 0;
	else return T->height;
}

更新树的高度

void updatagetheight(AVLTree T)
{
	T->height =  max(getheight(T->left),getheight(T->right))+1;
}

左左型
要做右旋

AVLTree LL(AVLTree A)
{
	AVLTree B = A->left;
	A->left = B->right;
	B->right = A;
	update(A);
	update(B);
	return B;
}

右右型
要做左旋

AVLTree RR(AVLTree A)
{
	AVLTree B = A->right;
	A->right = B->left;
	B->left = A;
	update(A)update(B);
	return B; 
}

左右型
要先做左旋再做右旋

AVLTree LR(AVLTree A)
{
	A->left = RR(A->left);
	return LL(A);
}

右左型
要先做右旋再做左旋

AVLTree RL(AVLTree A)
{
	A->right = LL(A->right);
	return RR(A);
}

最后重要的插入操作

AVLTree insert(AVLTree T,int X)
{
	if(!T){
		T=(AVLTree)malloc(sizeof(struct node));
		T->height = 1;
		T->data = X;
		T->left = T->right = NULL;
	}else if(X < T->data){
		T->left = insert(T->left,X);
		if(getheight(T->left)-getheight(T->right) ==2)
		{
			if(X<T->left->data){
				T= LL(T);
			}else{
				T = LR(T);
			}
		}
	}else{
		T->right = insert(T->right,X);
		if(getheight(T->left)-getheight(T->right) ==-2)
		{
			
			if(X>T->right->data){
				T = RR(T);
			}else{
				T = RL(T);
			}
		}
	}
	update(T);
	return T;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值