二叉查找树转换排序的循环双向链表

1.题目描述:

    输入一棵二叉查找树,将该二叉查找树转换成一个排序的循环双向链表。 
    要求不能创建任何新的结点,只调整指针的指向,也不能开辟新的存储空间O(1)

2.题目分析:

    首先照旧我们问题的解决思路,首先简化问题。(前提你应该了解二叉查找树和双向链表)

    如果没有任何的要求,那么我们自然会想到遍历整棵树然后排序出来之后重新构建一个链表即可,你想要什么样的都可以。

那么我们需要考虑的就是如何遍历?

然后慢慢复杂问题,不能新建立,那么就要在原来的基础上改,怎么改才能变过去呢?

这时,我要教你对于树的问题,有一招特别好用的就是画出来,很多问题其实画出来就容易了,只是脑袋想想除非你的记忆和几何能力很强。。。

3.代码描述:

/**
*二叉查找树转换成排序的循环双向链表 
*    创建如下形式的树 
*       6
*    2     7
*  1   4
*     3 5
*
**/ 

#include <cstdio>
#include <cstdlib> 
#include <iostream>

using namespace std;

typedef struct Node{
    int data;//数据域 
    struct Node* pLeft;//左子叶 
    struct Node* pRight;//右子叶 
}NODE, *PNODE;//NODE等价于struct Node,PNODE等价于struct Node* 

//在树中插入节点,为了创建树(迭代)
void insert_tree(PNODE root, PNODE newNode)
{
    PNODE nowNode = root;
    PNODE nextNode = root;
    
    //找到位置才停止 
    while(nextNode != NULL)
    {
        //如果要加入的元素大于当前节点,应该放到右边 
        if(newNode->data > nextNode->data)
        {
            nowNode = nextNode;
            nextNode = nextNode->pRight;
        }
        else
        {
            nowNode = nextNode;
            nextNode = nextNode->pLeft;
        }
    }
    if(newNode->data > nowNode->data)
    {
        nowNode->pRight = newNode;
    }
    else
    {
        nowNode->pLeft = newNode;
    }
} 

//创建树 
PNODE create_tree()
{
    int dataArray[7] = {6,7,2,1,4,3,5};
    PNODE root = (PNODE)malloc(sizeof(NODE));
    root->data = dataArray[0];
    root->pLeft = NULL;
    root->pRight = NULL;
    
    for(int i=1; i<=6; i++)
    {
        PNODE newNode = (PNODE)malloc(sizeof(NODE));
        newNode->data = dataArray[i];
        newNode->pLeft = NULL;
        newNode->pRight = NULL;
        insert_tree(root,newNode);
    }
    return root;
}

//连接两个链表 
PNODE connect_list(PNODE first, PNODE second)
{
    if(first == NULL)
        return second;
    if(second == NULL)
        return first;
    
    //分别取左右边的最后元素,用于形成循环和链接 
    PNODE first_last = first->pLeft;
    PNODE second_last = second->pLeft;
    
    first_last->pRight = second;
    second->pLeft = first_last;
    
    second_last->pRight = first;
    first->pLeft = second_last;
    
    return first;
}

//树-》链表 
PNODE tree_to_list(PNODE root)
{
    if(root == NULL)
        return NULL;
    
    //左边变成链表,右边变成链表,最后连起来 
    PNODE first = tree_to_list(root->pLeft);
    PNODE second = tree_to_list(root->pRight);
    
    root->pLeft = root;
    root->pRight = root;
    
    first = connect_list(first, root);
    first = connect_list(first, second);
    
    return first;
} 

//打印最终形成的链表所有元素 
void print_list(PNODE pHead)
{
    int a = pHead->data;
    while(pHead != NULL)
    {
        cout<<pHead->data<<" ";
        pHead = pHead->pRight;
        if(a == pHead->data)
            break;
    }
    cout<<endl;
    return;
}

int main() 
{
    PNODE root = NULL;
    root = create_tree();
    print_list(tree_to_list(root));
    return 0;
}

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值