将二叉搜索树转化为一个排序的双向链表

题目:
输入一颗二叉搜索树,将该二叉搜索树转换成一个排序的双向链表。要求不能创建任何新的结点,职能调整树中结点指针的指向。如下图所示:
这里写图片描述

由于要求转换之后的链表是排好序的,我们可以中序遍历树中的每一个结点,这回死因为中序遍历算法的特点是按照从小到大的顺序遍历二叉树的每一个节点。当遍历到根结点时,我们可以把书=树看成三部分:值为10的结点,根结点值为6的左子树,根结点值为14的右子树。根据排序链表的定义,值为10的结点将和它的左子树的最大一个结点(即值为8的结点)连接起来,同时它还将和右子树最小的结点(即值为12的结点)连接起来。
这里写图片描述
按照中序遍历的顺序,当我们遍历到根结点(值为10的结点)时,他的左子树已经转换为一个排序的链表了,并且处在链表中的最后一个结点是当前最大的结点。我们把值为8的结点和根结点连接起来,此时链表中的最后一个结点就是10了。接下来去便利右子树,并把根结点和柚子树章最小的结点连接起来。可以采用递归的想法。

struct BinaryTreeNode
{
    int m_nValue;
    BinaryTreeNode *m_pLeft;
    BinaryTreeNode *m_pRight;
};

BinaryTreeNode* Convert(BinaryTreeNode* pRootOfTree)
{
    BinaryTreeNode*pLastNodeInList = NULL;
    ConvertNode(pRootOfTree, &pLastNodeInList);
    //pLastNodeInList指向双向链表的尾结点
    //返回头结点
    BinaryTreeNode* pHeadOfList = pLastNodeInList;
    while (pHeadOfList != NULL&&pHeadOfList->m_pLeft != NULL)
        pHeadOfList = pHeadOfList->m_pLeft;

    return pHeadOfList;
}

void ConvertNode(BinaryTreeNode*pNode, BinaryTreeNode**pLastNodeInList)
{
    if (pNode == NULL)
        return;

    BinaryTreeNode*pCurrent = pNode;

    if (pCurrent->m_pLeft != NULL)
        ConvertNode(pCurrent->m_pLeft, pLastNodeInList);

    pCurrent->m_pLeft = *pLastNodeInList;
    if (*pLastNodeInList != NULL)
        (*pLastNodeInList)->m_pRight = pCurrent;

    *pLastNodeInList = pCurrent;

    if (pCurrent->m_pRight != NULL)
        ConvertNode(pCurrent->m_pRight, pLastNodeInList);
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
以下是将二叉搜索树转化排序双向链表的C语言实现代码: ```c #include <stdio.h> #include <stdlib.h> struct TreeNode { int val; struct TreeNode *left; struct TreeNode *right; }; struct TreeNode *prev = NULL; void convert(struct TreeNode *root, struct TreeNode **head) { if (root == NULL) { return; } convert(root->left, head); if (prev == NULL) { *head = root; } else { prev->right = root; root->left = prev; } prev = root; convert(root->right, head); } int main() { // 构造二叉搜索树 struct TreeNode *root = (struct TreeNode *) malloc(sizeof(struct TreeNode)); root->val = 4; root->left = (struct TreeNode *) malloc(sizeof(struct TreeNode)); root->left->val = 2; root->left->left = (struct TreeNode *) malloc(sizeof(struct TreeNode)); root->left->left->val = 1; root->left->left->left = NULL; root->left->left->right = NULL; root->left->right = (struct TreeNode *) malloc(sizeof(struct TreeNode)); root->left->right->val = 3; root->left->right->left = NULL; root->left->right->right = NULL; root->right = (struct TreeNode *) malloc(sizeof(struct TreeNode)); root->right->val = 5; root->right->left = NULL; root->right->right = NULL; // 将二叉搜索树转化排序双向链表 struct TreeNode *head = NULL; convert(root, &head); // 打印双向链表 struct TreeNode *p = head; while (p != NULL) { printf("%d ", p->val); p = p->right; } // 释放内存 free(root->left->left); free(root->left->right); free(root->left); free(root->right); free(root); return 0; } ``` 该算法的主要思路是中序遍历二叉搜索树,并在遍历过程中将节点连接为双向链表。具体实现时,需要用一个全局变量`prev`指向当前节点的前一个节点,以便在遍历当前节点时,将前一个节点和当前节点连接起来。另外,需要使用一个指向头节点的指针`head`,以便在遍历结束后返回头节点。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值