树相关

二叉树的相关递归操作

node* createTree(char a)
{
	if(a!='#')
	{
		node* root=new node;
		root->a=a;
		char b;
		cin>>b;
		root->lchild=createTree(b);
		cin>>b;
		root->rchild=createTree(b);
		
		return root;
	}
	else
		return NULL;
}

void preOrder(node* p)
{
	//函数的作用:对p进行判断如果p存储数据,则输出,然后对p的左右子节点进行相同的判断。
	if(p)
	{
		cout<<p->a<<endl;
		preOrder(p->lchild);
		preOrder(p->rchild);
	}
}


int leafCount(node* p)
{
	//函数作用:输出p节点构成的数的叶节点数量
	if(!p)
		return 0;
	else if(!p->lchild && !p->rchild)
		return 1;
	else
		return leafCount(p->lchild)+leafCount(p->rchild);
}


int treeDepth(node* p)
{
	if(!p)
		return -1;
		return 1+max(treeDepth(p->lchild),treeDepth(p->rchild));
}

node* copyTree(node* p)
{
	if(!p)return NULL;

	node* root=new node;
	root->a=p->a;
	root->lchild=copyTree(p->lchild);
	root->rchild=copyTree(p->rchild);
	
	return root;
}

堆相关操作:堆用数组存储同时根节点的数组下标为0.则i节点的左右子树的位置为2*i+1和2*i+2.

1.调整一颗左右子树满足堆性质,只有根节点需要重新构造堆的子树

//对i节点为根节点,且其左右子树以满足堆的树进构造,使得i及其子节点构成堆。n是堆的最后节点的位置(最后一位数据的数组下标)
void adjustInode(int* a, int i, int n)
{
    while(i<=(n-1)/2)//在此条件下,i是一定会有子节点的、下面分别判断:
    {
        if(2*i+2<=n)//i的左右节点都存在
        {
            int j=a[i*2+1]> a[i*2+2]? (i*2+1):(i*2+2);
            if(a[j] > a[i])
            {
                swap(a[j],a[i]);
                i=j;
            }
            else break;
        }
        else//i只存在左节点
        {
            if(a[i]<a[2*i+1])
            {
                swap(a[i],a[2*i+1]);
                i=2*i+1;
            }
            else break;
        }
    }
}


2.堆的插入

//1)堆的末位置+1,
//2)堆末位赋值新增的数
//3)游标i指向新增数位置,不断跟父亲比较,直到不需要交换
void pushHeap(int* a,int b,int& n)
{
	n++;
	a[n]=b;
	int i=n;
	while(i>1)
	{
		if(a[i]>a[(i-1)/2])
		{
			swap(a[i],a[(i-1)/2]);
			i=(i-1)/2;
		}
		else
			break;
	}
}
3.堆的删除

//1,将根节点数据用最后一位节点数据替代
//2,调整首节点为根的树,使其成为堆(左右子树已经满足堆性质)
void popHeap(int* a, int& n)
{
	a[0]=a[n];
	adjustInode(a,0,n-1);//
}
4.堆的创建

//将游标i从最后一颗子树开始(位置为(n-1)/2),不断前移直到堆的根(i=0),对树进行堆构造。
//能构造成功的原因是:i是从后向前移动的,其移动到某位置后,其左右子树必然已经构成了堆。
void createHeap(int* a,int& n)
{
	int j=(n-1)/2;
	for(int i=j;i>=0;i--)
		adjustInode(a,i,n);
}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值