IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> 数据结构与算法 -> C++算法题:关于树的算法 -> 正文阅读

[数据结构与算法]C++算法题:关于树的算法

问题1:输入一棵二元查找树,将该二元查找树转换成一个排序的双向链表。要求不能创建任何新的结点,只调整指针的指向。

什么是二元查找树?

比如:

转换成双向链表的顺序是:

1? 3? 4? 6? 7? 8? 10? 13? 14?

步骤一:建立二叉搜索树

struct BSTreeNode  
{  
    int value;  
    BSTreeNode *left;  
    BSTreeNode *right;  
};

BSTreeNode * Insert(BSTreeNode *p, int x)  
{  
    if(p == NULL)  
    {  
//最终新加的元素将会被赶到最下面,新建这个节点;这么做是遵循二元查找树定义的
//前面也可插入只是太麻烦
        p = new BSTreeNode;  
        p->value = x;  
        p->left = NULL;  
        p->right = NULL;  
    }  
    else  
    {  
//如果x小于头结点,加到左边
        if(p->value > x)  
            p->left = Insert(p->left, x);  
//如果x大于头结点,加到右边
        if(p->value < x)  
            p->right = Insert(p->right, x);  
    }  
    return p;  
} 

步骤二:遍历二元查找树

void Traverse(BSTreeNode *p) //中序遍历  
{  
    if(p == NULL)  
        return;  
    Traverse(p->left);      //左
    cout<<p->value<<' ';  //根
    Traverse(p->right);    //右
}  

步骤三:转换为双向链表(比我小之中取最大,比我大之中取最小,分列我两侧)

BSTreeNode * Convert(BSTreeNode *node)  
{  
    if(node == NULL)  
        return NULL;  
    BSTreeNode *leftMax,*rightMin;  
    leftMax = node->left;      
    rightMin = node->right;  
    //找到左子树的最大结点  
    while(leftMax != NULL && leftMax->right != NULL)  
        leftMax = leftMax->right;  
    //找到右子树的最小结点  
    while(rightMin != NULL && rightMin->left != NULL)  
        rightMin = rightMin->left;  
    //递归求解  在调整指针之前,先递归
    Convert(node->right);   
    Convert(node->left);  
    //将左右子树同根结点连起来,只不过是以兄弟的关系  
    if(leftMax != NULL)  
        leftMax->right = node;  
    if(rightMin != NULL)  
        rightMin->left = node;  
    node->left = leftMax;  
    node->right = rightMin;  
    return node;  
}  

问题2:输入一颗二元查找树,将该树转换为它的镜像,即在转换后的二元查找树中,左子树的结点都大于右子树的结点。用递归和循环两种方法完成树的镜像转换

struct BSTreeNode    
{    
    int value;    
    BSTreeNode *left;    
    BSTreeNode *right;    
}; 

解法一:用递归

//函数功能 : 输入一颗二元查找树,将该树转换为它的镜像  
//函数参数 : pRoot为根结点  
//返回值 :   根结点  
BSTreeNode * Mirror_Solution1(BSTreeNode * pRoot)  
{  
    if(pRoot != NULL)  
    {  
 //必须记住这个节点,不然下面的赋值将把原来的关系解除,就找不到原来的pRoot->left;了
        BSTreeNode * pRight = pRoot->right;  
        BSTreeNode * pLeft = pRoot->left; 
        pRoot->left = Mirror_Solution1(pRight);  //转化右子树  
        pRoot->right = Mirror_Solution1(pLeft);  //转化左子树  
    }  
    return pRoot;  
} 

解法二:用循环

BSTreeNode * Mirror_Solution2(BSTreeNode * pRoot)  
{  
    if(pRoot != NULL)  
    {  
        stack<BSTreeNode *> stk;   //辅助栈  
        stk.push(pRoot);           //压入根结点  
        while(stk.size())  
        {  
            BSTreeNode *pNode = stk.top();  
            BSTreeNode *pLeft = pNode->left;  
            BSTreeNode* pRight = pNode->right;  
            stk.pop();  
  
            if(pLeft != NULL)  
                stk.push(pLeft);  
            if(pRight != NULL)  
                stk.push(pRight);  
            pNode->left = pRight;  //交换左右子女  
            pNode->right = pLeft;  
        }  
    }  
    return pRoot;  
} 

问题3:输入一颗二元树,从上往下按层打印树的每个结点,同一层中按照从左往右的顺序打印。

//跟上一篇的镜像二叉树类似
//函数功能 : 按层次遍历二元树  
//函数参数 : pRoot指向根结点  
//返回值 :   无  
void LevelReverse(BSTreeNode *pRoot)  
{  
    if(pRoot == NULL)  
        return;  
  
    queue<BSTreeNode *> nodeQueue;  
    nodeQueue.push(pRoot);  
    while(nodeQueue.size())  
    {  
        BSTreeNode * pNode = nodeQueue.front(); //取队首元素  
        nodeQueue.pop(); //必须出队列  
        if(pNode->left)  //左子女  
            nodeQueue.push(pNode->left);  
        if(pNode->right) //右子女  
            nodeQueue.push(pNode->right);  
  
        cout<<pNode->value<<' ';  
    }  
} 

问题4:输入一棵二叉树的根结点,判断该树是不是平衡二叉树。如果某二叉树中任意结点的左右子树的深度相差不超过1,那么它就是一棵平衡二叉树。例如下图中的二叉树就是一棵平衡二叉树

struct BinaryTreeNode  
{  
    int data;  
    BinaryTreeNode *pLeft;  
    BinaryTreeNode *pRight;  
};  
//函数功能 : 判断二叉树是不是平衡的  
//函数参数 : pRoot为根结点,pDepth为根结点的深度。  
//返回值 :   是否平衡的  
bool IsBalanced(BinaryTreeNode *pRoot, int *pDepth)  
{  
    if(pRoot == NULL)  
    {  
        *pDepth = 0;  
        return true;  
    }  
    int leftDepth, rightDepth; //左右子树的深度  
    //只有左右子树已经是平衡,才能比较当前节点是不是平衡
    if(IsBalanced(pRoot->pLeft, &leftDepth)&&  
        IsBalanced(pRoot->pRight, &rightDepth))  
    {  
        int diff = leftDepth - rightDepth;  
        if(diff == 0 || diff == 1 || diff == -1)  //相差为0或1或-1  
        {  
            *pDepth = 1 + (leftDepth > rightDepth ? leftDepth: rightDepth);   
            return true;  
        }  
        else  
     //如果返回一个false则全盘都是false
            return false;  
    }  
    return false;  
}  

  数据结构与算法 最新文章
【力扣106】 从中序与后续遍历序列构造二叉
leetcode 322 零钱兑换
哈希的应用:海量数据处理
动态规划|最短Hamilton路径
华为机试_HJ41 称砝码【中等】【menset】【
【C与数据结构】——寒假提高每日练习Day1
基础算法——堆排序
2023王道数据结构线性表--单链表课后习题部
LeetCode 之 反转链表的一部分
【题解】lintcode必刷50题<有效的括号序列
上一篇文章      下一篇文章      查看所有文章
加:2022-05-13 11:54:55  更:2022-05-13 11:55:27 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年11日历 -2024/11/26 4:36:55-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码