随笔 -( 二叉树 )

二叉搜索树及其操作与应用
二叉搜索树的操作集
BinTree Insert( BinTree BST, ElementType X )
{
	if(BST==NULL)
	{
		BST=(BinTree)malloc(sizeof(BinTree));
		BST->Data=X;
		BST->Left=NULL;
		BST->Right=NULL;
	}
	else
	{
		if(X>BST->Data)
			BST->Right=Insert(BST->Right,X);
		else if(X<BST->Data)
			BST->Left=Insert(BST->Left,X);
	}
	return BST;	
}
BinTree Delete( BinTree BST, ElementType X )
{
	if(BST==NULL)
		printf("Not Found\n");
	else
	{ 
		if(X>BST->Data)
			BST->Right=Delete(BST->Right,X);
		else if(X<BST->Data)
			BST->Left=Delete(BST->Left,X);
		else 
		{
			if(BST->Left&&BST->Right)
			{
				Position tmp=FindMin(BST->Right);
				BST->Data=tmp->Data;
				BST->Right=Delete(BST->Right,BST->Data);
			}
			else
			{
				Position tmp=BST;
				if(BST->Left)
					BST=BST->Left;
				else
					BST=BST->Right;
				free(tmp);
			}
		}
	}
	return BST;
}
Position Find( BinTree BST, ElementType X )
{
	if(BST)
	{
		if(X==BST->Data)
			return BST;
		else if(X>BST->Data)
			return Find(BST->Right,X);
		else
			return Find(BST->Left,X);
 
	}
	return BST;
}
Position FindMin( BinTree BST )
{
    if(BST)
	{
        while(BST->Left)
            BST=BST->Left;
    } 
    return BST; 
} 
Position FindMax( BinTree BST )
{
    if(BST)
	{
        while(BST->Right)
            BST=BST->Right;
    } 
    return BST; 
}
二叉搜索树中的最近公共祖先
int find(Tree T,int x)
{
	if(!T) return 0;
	if(x==T->Key) return 1;
	if(x<T->Key) return find(T->Left,x);
	else return find(T->Right,x);
}                                                         
int LCA( Tree T, int u, int v )
{
	if(!T) return ERROR;
	if(!find(T,u)||!find(T,v)) return ERROR;
	int data=T->Key;
	if((u>data&&v<data)||(u<data&&v>data)) return data;
	if(u==data||v==data) return data;
	if(u>data) return LCA(T->Right,u,v);
	else return LCA(T->Left,u,v);
}
统计二叉树叶子结点个数
int LeafCount(BiTree T)
{
    int count;
    if(T==NULL) count=0;
    else if(T->lchild==NULL&&T->rchild==NULL) count=1;
    else count=LeafCount(T->lchild)+LeafCount(T->rchild);
    return count;
}
二叉树的三种遍历(先序、中序和后序)
void Preorder(BiTree T)
{
	if(T)
	{
		printf(" %c",T->data);
		Preorder(T->lchild);
		Preorder(T->rchild);
	}
}
void Inorder(BiTree T)
{
	if(T)
	{
		Inorder(T->lchild);
		printf(" %c", T->data);
		Inorder(T->rchild);
	}
}
void Postorder(BiTree T)
{
	if(T)
	{
		Postorder(T->lchild);
		Postorder(T->rchild);
		printf(" %c", T->data);		
	}
}
二叉树的非递归遍历
void InorderTraversal( BinTree BT )
{
	BinTree t=BT;
	Stack s=CreateStack();
	while(t||!IsEmpty(s))
	{
		while(t)
		{
			Push(s,t);
			t=t->Left;
		}
		if(!IsEmpty(s))
		{
			t=Pop(s);
			printf(" %c",t->Data);
			t=t->Right;
		}
	}
}
void PreorderTraversal( BinTree BT )
{
    BinTree t=BT;
    Stack s=CreateStack();
    while(t||!IsEmpty(s))
    {
        while(t)
        {
            Push(s,t);
            printf(" %c",t->Data);
            t=t->Left;
        }
        if(!IsEmpty(s))
        {
            t=Pop(s);
            t=t->Right;
        }
    }
}
void PostorderTraversal( BinTree BT )
{
    BinTree t=BT;
    Stack s=CreateStack();
    while(t||!IsEmpty(s))
    {
        while(t)
        {
            Push(s,t);
            t->flag=1;
            t=t->Left;
        }
        if(!IsEmpty(s))
        {
            t=Pop(s);
            if(t->flag==1)
            {
                Push(s,t);
                t->flag = 2;
                t=t->Right;
            }
            else
            {
                printf(" %c",t->Data);
                t=NULL;
            }
        }
    }
} 
是否二叉搜索树
bool IsBST ( BinTree T )
{
    if(T)
	{
        if(T->Left)
		{
            if(T->Left->Data>T->Data) return false;
            if(T->Left->Right)
                if(T->Left->Right->Data>T->Data) return false;
            else return IsBST(T->Left);
        }
        if(T->Right)
		{
            if(T->Right->Data<T->Data) return false;
            if(T->Right->Left)
                if(T->Right->Left->Data<T->Data) return false;
            else return IsBST(T->Right);
        }
    }
    return true;
}
7-41 还原二叉树 (25分)
#include<iostream>
#include<cstdio>
using namespace std;
const int maxn=1e5+10;
int n;
char a[110],b[110];
struct node
{
	int l;
	int r;
}tree[maxn];
int build(int l1,int r1,int l2,int r2)
{
	if(l1>r1) return -1;
	int root=a[l1],pos=l2;
	while(b[pos]!=root) pos++;
	int len=pos-l2;
	tree[root].l=build(l1+1,l1+len,l2,pos-1);
	tree[root].r=build(l1+len+1,r1,pos+1,r2);
	return root;
}
int look(int root)
{
	if(root==-1) return 0;
	else return max(look(tree[root].l),look(tree[root].r))+1;
}
int main()
{
	cin>>n;
	for(int i=1;i<=n;i++) cin>>a[i];
	for(int i=1;i<=n;i++) cin>>b[i];
	build(1,n,1,n);
	cout<<look(a[1]);
    return 0;
}
7-42 玩转二叉树 (25分)
#include<iostream>
#include<string>
#include<map>
#include<set>
//#include<unordered_map>
#include<queue>
#include<cstdio>
#include<vector>
#include<cstring>
#include<algorithm>
#include<iomanip>
#include<cmath>
#include<fstream>
#define X first
#define Y second
#define INF 0x3f3f3f3f
#define pii pair<int, int>
//#define pdi pair<double,int>
using namespace std;
typedef long long ll;
typedef unsigned long long llu;
const int maxn=1e5+10;
int n,a[110],b[110],ans[110],cnt; 
struct node
{
	int l;
	int r;
}tree[1010];
int build(int l1,int r1,int l2,int r2)
{
	if(l1>r1) return -1;
	int root=b[l2],pos=l1;
	while(a[pos]!=root) pos++;
	int len=pos-l1;
	tree[root].l=build(l1,pos-1,l2+1,l2+len);
	tree[root].r=build(pos+1,r1,l2+len+1,r2);
	return root;
} 
void change(int root)
{
	if(root==-1) return ;
	if(tree[root].l==-1&&tree[root].r==-1) return ;
	swap(tree[root].l,tree[root].r);
	change(tree[root].l);
	change(tree[root].r);
}
void pint(int root)
{
	queue<int>q;
	q.push(root);
	while(q.size())
	{
		int cur=q.front();
		q.pop();
		ans[cnt++]=cur;
		if(tree[cur].l!=-1) q.push(tree[cur].l);
		if(tree[cur].r!=-1) q.push(tree[cur].r);
	}
	for(int i=0;i<cnt;i++)
	{
		if(i==0) printf("%d",ans[i]);
		else printf(" %d",ans[i]);
	}
}
int main( )
{
	scanf("%d",&n);
	for(int i=1;i<=n;i++) scanf("%d",&a[i]);
	for(int i=1;i<=n;i++) scanf("%d",&b[i]);
	build(1,n,1,n);
	change(b[1]);
	pint(b[1]);
	return 0;
}
 
树的遍历(25分)
#include<iostream>
#include<string>
#include<map>
#include<set>
//#include<unordered_map>
#include<queue>
#include<cstdio>
#include<vector>
#include<cstring>
#include<algorithm>
#include<iomanip>
#include<cmath>
#include<fstream>
#define X first
#define Y second
#define INF 0x3f3f3f3f
#define pii pair<int, int>
//#define pdi pair<double,int>
using namespace std;
typedef long long ll;
typedef unsigned long long llu;
const int maxn=1e5+10;
int n,a[110],b[110],ans[110],cnt; 
struct node
{
	int l;
	int r;
}tree[1010];
int build(int l1,int r1,int l2,int r2)
{
	if(l1>r1) return -1;
	int root=a[r2],pos=l1;
	while(b[pos]!=root) pos++;
	int len=pos-l1;
	tree[root].l=build(l1,pos-1,l2,l2+len-1);
	tree[root].r=build(pos+1,r1,l2+len,r2-1);
	return root;
}
void pint(int root)
{
	queue<int>q;
	q.push(root);
	while(q.size())
	{
		int cur=q.front();
		q.pop();
		ans[cnt++]=cur;
		if(tree[cur].l!=-1) q.push(tree[cur].l);
		if(tree[cur].r!=-1) q.push(tree[cur].r);
	}
	for(int i=0;i<cnt;i++)
	{
		if(i==0) printf("%d",ans[i]);
		else printf(" %d",ans[i]);
	}
}
int main( )
{
	scanf("%d",&n);
	for(int i=1;i<=n;i++) scanf("%d",&a[i]);
	for(int i=1;i<=n;i++) scanf("%d",&b[i]);
	build(1,n,1,n);
	pint(a[n]);
	return 0;
}
 
7-44 搜索树判断 (25分)
#include<iostream>
#include<cstdio>
#include<vector>
using namespace std;
const int maxn=1e5+10;
int n,a[1010];
vector<int>v;
void getv(int l,int r,int flag)
{
	int root=a[l];
	int left=l+1,right=r;
	if(!flag)//原像 
	{
		while(left<=r&&a[left]<root) left++;
		while(right>l&&a[right]>=root) right--;
	} 
	else//镜像 
	{
		while(left<=r&&a[left]>=root) left++;
		while(right>l&&a[right]<root) right--;
	}
	if(left-right!=1) return ;
	getv(l+1,right,flag);
	getv(left,r,flag);
	v.push_back(root);
}
int main()
{
	cin>>n;
	for(int i=1;i<=n;i++) cin>>a[i];
	getv(1,n,0);
//	cout<<"!!"<<endl;
	if(v.size()!=n)
	{
		v.clear();
		getv(1,n,1);
	}
	if(v.size()==n)
	{
		cout<<"YES"<<endl;
		for(int i=0;i<n;i++)
		{
			if(i==0) cout<<v[i];
			else cout<<' '<<v[i];
		}
	}
	else cout<<"NO"<<endl;
    return 0;
}
7-45 是否完全二叉搜索树 (30分)
#include<iostream>
#include<string>
#include<cstdio>
using namespace std;
typedef long long ll;
typedef unsigned long long llu;
const int maxn=1e5+10;
int n,a[110],flag,cnt,tree[1010];
void build(int p,int pos)
{
	if(tree[p]==0) tree[p]=a[pos];
	else
	{
		if(a[pos]>tree[p]) build(p<<1,pos);
		else build(p<<1|1,pos);
	}
	return ;
}
int main( )
{
	scanf("%d",&n);
	for(int i=1;i<=n;i++) scanf("%d",&a[i]),build(1,i);
	for(int i=1;i<1010;i++)
	{
	    if(tree[i])
		{ 
	 	    if(flag) cout<<" ";
	 	    else flag=1;
			cout<<tree[i];
	 	    cnt=i;
		}
	} 
	if(cnt>n) cout<<endl<<"NO"<<endl;
	else cout<<endl<<"YES"<<endl;
	return 0;
}
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值