【树】二叉树转为双向链表

这篇博客主要介绍了如何将二叉树转换为双向链表的递归方法,包括找到节点的前驱和后驱节点,然后进行连接。此外,还提到了其他树的遍历方法,如非递归遍历和广度遍历的不同形式。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

目录:

1.【树】二叉树的非递归遍历(栈&Morris)

2.【树】二叉树转为双向链表

3.【树】树的广度遍历(1.打成一行 2.按层打成普通多行 3.按层打成之字形多行)


思路:

递归:

当前节点是root。

if(左子树不空)

找到root的前驱节点predecessor

把它跟root连起来

if(右子树不空)

找到root的后驱节点successor

把它跟root连起来。


最后返回的应为双向链表的头节点,所以再一直往左找就行啦。


**********************
二叉树->双向链表
**********************
Convert函数返回的是root节点,BinTreeToDLL函数返回的是最终答案(双向链表double-linked-list的头节点)

TreeNode* Convert(TreeNode* root)
{
    if (root == NULL)
        return root;
 
    // Convert the left subtree and link to root
    if (root->left != NULL) //此处先判断了左子树不空! 所以while循环条件里无需担心predecessor为NULL的情况
    {
        // Convert the left subtree
        TreeNode* predecessor = Convert(root->left);
 
        // Find inorder predecessor. After this loop, predecessor will point to the inorder predecessor
        while(predecessor->right != NULL)
			predecessor = predecessor->right;
 
        // Make root as next of the predecessor and Make predecssor as previous of root
        predecessor->right = root;
        root->left = predecessor;
    }
 
    // Convert the right subtree and link to root
    if (root->right!=NULL)
    {
        // Convert the right subtree
        TreeNode* successor = Convert(root->right);
 
        // Find inorder successor. After this loop, successor will point to the inorder successor
        while(successor->left != NULL)
			successor = successor->left
		
        // Make root as previous of successor and Make successor as next of root
        successor->left = root;
        root->right = successor;
    }
 
    return root;
}
 

TreeNode* BinTreeToDLL(TreeNode* root) {
    if (root == NULL)
        return root;
 
    // Convert to DLL using Convert()
    TreeNode* listHead = Convert(root);
 
    // Convert() returns root node of the converted
    // DLL.  We need pointer to the leftmost node which is
    // head of the constructed DLL, so move to the leftmost node
    while (listHead->left != NULL)
        listHead = listHead->left;
 
    return listHead;
}



另一种AC写法:(没上面的好理解)

TreeNode* Convert(TreeNode* pRoot)
{
	//1.递归出口
	if(pRoot == NULL || pRoot->left == NULL && pRoot->right == NULL)
		return pRoot;
	//2.将左子树转成doubleList
	TreeNode* leftHead = Convert(pRoot->left);
	//3.找到左子树的尾结点
	TreeNode* leftTail = leftHead;
	while(leftTail != NULL && leftTail->right != NULL) {
		leftTail = leftTail->right;
	}
	//4.若左子树不为空,把pRoot加到【双向链接】doubleList尾部;否则,把leftHead指向pRoot【返回值】
	if(leftTail){
		leftTail->right = pRoot;
		pRoot->left = leftTail;
	}
	else
		leftHead = pRoot;
	//5.将右子树转成doubleList
	TreeNode* rightHead = Convert(pRoot->right);
	//6.若右子树不为空,就加到【双向链接】pRoot后面
	if(rightHead) {
		pRoot->right = rightHead;
		rightHead->left = pRoot;
	}
        
	return leftHead;
}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值