LeetCode(树的练习题)

目录

1.以二叉链表作存储结构,编写一个算法将二叉树左、右子树进行交换的算法。

2.一棵具有n个结点的完全二叉树存放在二叉树的顺序存储结构中,试编写非递归算法对该树进行中序遍历。

3.判别两棵二叉树是否等价。

4.设计一个实现一棵二叉树复制的算法。

5.编写一个将二叉树的所有叶子结点从左向右链接成单链表的算法。

6.设具有n个结点的完全二叉树采用顺序存储结构,试写一个算法将该顺序存储结构转换为二叉链式存储结构。

7.7.设具有n个结点的二叉树采用二叉链式存储结构,试写出一个算法将该二叉链式存储结构转换为顺序存储结构。

8.获取节点值为x的层次

9.获取节点的路径

10.先序遍历倒数第k个节点


经典练习题

1.以二叉链表作存储结构,编写一个算法将二叉树左、右子树进行交换的算法。

void SwapSubTree(ListNode *root)
{
	ListNode *temp;
	if (root)
	{
		temp = root->lchild;
		root->lchild = root->rchild;
		root->rchild = temp;
		SwapSubTree(&((*T)->lchild));
		SwapSubTree(&((*T)->rchild));
	}
}

2.一棵具有n个结点的完全二叉树存放在二叉树的顺序存储结构中,试编写非递归算法对该树进行中序遍历。

void Inorder(int  root, int n ,T trees[])//n个节点的完全二叉树,存储在数组trees中
{
	if(root == 0 ) return;
        
    stack<int> s;
	while( root <=n ||  !s.empty() )
	{
		if(root <=n) {
            s.push(root); 
            root = root*2;        //左子树入栈
        }
		else 
		{
			root = s.top();       //取出左子树栈顶访问
            visit (trees[root]);
            s.pop();
            root = root*2+1;     //转向右子树

		}
	}		
	
}

3.判别两棵二叉树是否等价。

如果T1和T2都是空二叉树,或T1和T2的根结点的值相同,并且T1的左子树与T2的左子树是等价的;T1的右子树与T2的右子树是等价的。

原题

bool judgetree(treenode *s1,treenode *s2){

    if(s1==NULL&&s2==NULL)
    {
        return true;
    }
    if(s1==NULL||s2==NULL)
    {
        return false;
    }
    if(s1->val!=s2->val)
        return false;
    return judgetree(s1->left,s2->left)&&judgetree(s1->right,s2->right);
}

4.设计一个实现一棵二叉树复制的算法。

void copytree(treenode *from, treenode * & to )//拷贝from到to树,注意to参数为引用
{	
	if (from == NULL) {to = NULL; return;}
	to = new treenode ;to->data = from->data ; //1/拷贝根节点
	copytree(from->lchild,to->lchild);//2/拷贝左子树
 	copytree(from->rchild,to->rchild)//3/拷贝右子树

}

5.编写一个将二叉树的所有叶子结点从左向右链接成单链表的算法。

void Creatlist(BinaryTreeNode*T,listNode*&L)//利用先序遍历递归,用链表L把结点串起来
{

    if (T != NULL) {
        if (T->left == NULL&&T->right == NULL) //如果左右子树为空,则为叶子结点
        {
            listNode *temp = new listNode;  //串起来
            temp->data = T->value;
            L->next = temp;
            L = L->next;    

        }
        Creatlist(T->left,L);     //递归左子树
        Creatlist(T->right,L);    //递归右子树
    }
    L->next = NULL;
}

原博客: 

用递归法把二叉树的叶子结点按从左到右的顺序连成一个单链表_小树学信奥-CSDN博客_设计一个算法将二叉树的叶结点按从左到右

6.设具有n个结点的完全二叉树采用顺序存储结构,试写一个算法将该顺序存储结构转换为二叉链式存储结构。

void transfer(int  from, int n ,T trees[], treenode * & to )//拷贝from到to树,注意to参数为引用
{	
	if (form == 0 || from > n ) {to = NULL; return;}
	to = new treenode ;to->data =trees[ from] ; //1/拷贝根节点
	transfer(from*2,to->lchild);//2/拷贝左子树
 	transfer(from*2+1,to->rchild)//3/拷贝右子树

}

7.7.设具有n个结点的二叉树采用二叉链式存储结构,试写出一个算法将该二叉链式存储结构转换为顺序存储结构。

//注意顺序结构需要的空间为n?当然不是,因为不会完全二叉树

void transfer(T trees[],int to, treenode *  from )//值为0代表空树 调用时trees值全部为0;to为1;
{	
	if (form ==NULL )  return;
	trees[ to]= from->data ; //1/拷贝根节点
	transfer(trees,to*2,from->lchild);//2/拷贝左子树
 	transfer(trees,to*2+1,from->rchild)//3/拷贝右子树

}

8.获取节点值为x的层次

void binTree::getLevel3(TreeNode * proot,int x, int &leveloutput)
{
	int static level = 1 ;
	if (proot != NULL)
	{
		if (proot ->data  == x )  leveloutput = level;  //只赋值一次
	
		++level;//进入下一层,层次增1

		getLevel3(proot->lchild ,x,leveloutput);	
		//--level;++level;  //所以这里可以不要这2个语句,刚好抵消

		getLevel3(proot->rchild ,x,leveloutput);

		--level;//退回到上一层,层数减1,这是回溯步

	}
}

9.获取节点的路径

类似第八题的思路 

void binTree::getPath(TreeNode * proot,int x,stack <int>  &sx, bool &over )
{
	if (!over  && proot != NULL)
	{
		sx.push (proot ->data);//进入下一层,该节点进栈
		if (proot ->data  == x )  over = true;
		
		if (!over) 
        getPath(proot->lchild ,x,sx,over);     //如果找到,直接退出,否则遍历左子树	
		if (!over) 
        getPath(proot->rchild ,x,sx,over);    //如果左子树找到,直接退出,否则遍历右子树
		if (!over) 
            sx.pop ();
         //退回到上一层,节点出栈,这是回溯步,如果已经发现,不退栈,保持找到的路径值,否则直接退出
	}

}

10.先序遍历倒数第k个节点

//先序倒数第k个节点,即正数第n-k+1 个节点,这个实现略
//可以采用另外一个做法来实现:先序遍历的逆序列刚好就是使用右、左、根遍历的序列,
//所以倒数第k个先序序列,刚好就是使用先右再左最后根的遍历次序的 第k个节点

TreeNode * getLastNumKpreorder(TreeNode * proot,int k)//遍历全部节点
	{
		static int count = 0 ;
		static TreeNode *  pnumK = NULL;//这个变量不是静态,可以吗?为什么

		if (proot  != NULL)
		{
			
			getLastNumKpreorder(proot->rchild ,k);//先遍历右子树		
		    getLastNumKpreorder(proot->lchild ,k);//再遍历左子树	
			//最后访问操作根
			++count;
			if (count == k )  pnumK = proot;
		}
		return pnumK;
}//可以使用外部变量或者引用参数代替内部静态变量来实现

  • 2
    点赞
  • 10
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值