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;
}