完全二叉树指向同一层的相邻结点

本文介绍了一种算法,用于给完全二叉树的所有节点添加pNext指针,使其指向同一层的相邻节点。通过迭代遍历的方式实现了节点间的连接,并保持了较低的时间复杂度O(n)和空间复杂度O(1)。

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

题目:对于一颗完全二叉树,要求给所有节点加上一个pNext指针,指向同一层的相邻节点;如果当前节点已经是该层的最后一个节点,则将pNext指针指向NULL;给出程序实现,并分析时间复杂度和空间复杂度。

答:时间复杂度为O(n),空间复杂度为O(1)。

#include "stdafx.h"
#include <iostream>
#include <fstream>
#include <vector>

using namespace std;

struct TreeNode 
{
    int m_nValue;
    TreeNode *m_pLeft;
    TreeNode *m_pRight;
    TreeNode *pNext;
};

//假定所创建的二叉树如下图所示
/*
                                             1
                                          /     \
                                         2       3
                                        / \      / \
                                       4   5    6   7
                                      / \  / \  / \
                                     8   9 10 11 12 13
*/
void CreateBitree(TreeNode *&pNode, fstream &fin)
{
    int dat;
    fin>>dat;
    if(dat == 0)
    {
        pNode = NULL;
    }
    else 
    {
        pNode = new TreeNode();
        pNode->m_nValue = dat;
        pNode->m_pLeft = NULL;
        pNode->m_pRight = NULL;
        pNode->pNext = NULL;
        CreateBitree(pNode->m_pLeft, fin);      
        CreateBitree(pNode->m_pRight, fin); 
    }
}

//完全二叉树指向同一层的相邻结点
void Solution(TreeNode *pHead)
{
    if (NULL == pHead)
    {
        return;
    }
    vector<TreeNode*> vec;
    vec.push_back(pHead);
    TreeNode *pre = NULL;
    TreeNode *pNode = NULL;
    int cur = 0;
    int last = 0;
    while(cur < vec.size())
    {
        last = vec.size();
        while (cur < last)
        {
            if (NULL == pre)
            {
                pre = vec[cur];
            }
            else
            {
                pre->pNext = vec[cur];
            }
            if (NULL != vec[cur]->m_pLeft)
            {
                vec.push_back(vec[cur]->m_pLeft);
            }
            if (NULL != vec[cur]->m_pRight)
            {
                vec.push_back(vec[cur]->m_pRight);
            }
            pre = vec[cur];
            cur++;
        }
        pre->pNext = NULL;
        pre = NULL;
    }
}

int _tmain(int argc, _TCHAR* argv[])
{
    fstream fin("tree.txt");
    TreeNode *pHead = NULL;
    TreeNode *pNode = NULL;
    CreateBitree(pHead, fin);
    Solution(pHead);

    while (NULL != pHead)
    {
        cout<<pHead->m_nValue<<"  ";
        pNode = pHead->pNext;
        while (NULL != pNode)
        {
            cout<<pNode->m_nValue<<"  ";
            pNode = pNode->pNext;
        }
        cout<<endl;
        pHead = pHead->m_pLeft;
    }

    cout<<endl;
    return 0;
}

运行界面如下:

建造二叉树用到的tree.txt文件如下:

1 2 4 8 0 0 9 0 0 5 10 0 0 11 0 0 3 6 12 0 0 13 0 0 7 0 0
在C语言中,从二叉树中删除指定节点`*p`所在的次通常涉及到深度优先搜索(DFS),特别是前序遍历或次遍历。这里假设我们有一个结构化的二叉树,每个节点都有左右子节点指向其父节点的指针。 首先,你需要创建一个函数来找到指定节点`*p`,并标记它为已删除。然后,你可以递归地处理当前的所有节点,如果发现有需要删除的节点,就移除它,并更新相邻节点的关系,如调整它们的左/右子节点指针。 以下是简单的步骤: 1. **找到目标节点**: - 如果`*p`不是根节点,先访问它的父节点; - 比较`*p`的值节点的左右子节点值,找到对应位置; - 如果找到,更新父节点的子节点指针,使其跳过`*p`。 2. **删除当前**: - 如果`*p`是当前的第一个节点,那么只需将下一的头节点设为`*p`的下一个兄弟节点(如果有); - 否则,删除`*p`并让它的直接前驱或后继接手其子节点(如果存在)。 3. **递归处理下一**: - 如果`*p`有右孩子(或左孩子,取决于次遍历的方向),继续在右孩子的子树中查找和删除指定节点所在的次。 注意,这个过程假定二叉树是一个完整的次结构,对于高度不确定或者非完整的情况,可能需要更复杂的算法。 ```c // 假设二叉树节点结构如下 typedef struct TreeNode { int val; struct TreeNode *left; struct TreeNode *right; struct TreeNode *parent; // 父节点指针 } TreeNode; void deleteLevel(TreeNode** root, TreeNode* p) { if (*root == NULL || p == NULL) return; // 检查根节点是否存在 // 找到*root的位置并删除它 while (*root != NULL && (*root)->val != p->val) { *root = (*root)->left ? (*root)->left : (*root)->right; } if (*root == NULL) return; // 如果没找到,说明不在树中 // 删除*root以及调整父节点指针 if (p->parent->left == *root) p->parent->left = (*root)->right; else p->parent->right = (*root)->right; if ((*root)->right != NULL) (*root)->right->parent = p->parent; // 更新右孩子的新父节点 } ```
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值