二叉树转换成双向链表
题目:
将一个搜索二叉树转换成一个有序的双向链表
思路:
具体用递归的思想,用当前函数的指针节点与左子树的双向循环链表的尾节点进行指针的指向更新,当前的指针节点与右子树的双向循环链表的头结点进行指针的指向更新,最后递归函数返回值为当前形成的双向循环链表的尾节点。
具体代码如下:
#include <iostream>
#include <queue>
#include <algorithm>
using namespace std;
typedef struct node{
node* left;
node* right;
int data;
}node,*pnode, *root;
//层次遍历打印
void printTree(pnode n)
{
queue<pnode> q;
if(n != NULL)
{
q.push(n);
}
while(!q.empty())
{
pnode p = q.front();
q.pop();
cout<<p->data<<"\t";
if(p->left != NULL)
q.push(p->left);
if(p->right != NULL)
q.push(p->right);
}
cout<<endl;
}
//递归函数
pnode treeToDoubleList(pnode n)
{
if(n!= NULL)
{
pnode retNode = n;//初始化当前点返回的节点
pnode right1 = treeToDoubleList(n->left);
//更新左子树双向链表最后一个节点与当前点的指针指向
n->left = right1;
if(right1 != NULL)
right1->right = n;
pnode right2 = treeToDoubleList(n->right);
//更新右子树双向链表最前面的节点与当前点的指针指向
pnode p = right2;
if(p != NULL)
{
retNode = p;//如果不为空那么返回的节点就是右子树的双向链表的最后一个节点
while(p->left != NULL)//找到最左边的节点
p = p->left;
p->left = n;
}
n->right = p;
return retNode;
}
return NULL;
}
void printDoubleList(pnode n)
{
pnode p = n;
while(p->left!= NULL)
p = p->left;
while(p!=NULL)
{
cout << p->data << "\t";
p = p->right;
}
}
//插入节点
void InsertNode(pnode n, int a)
{
if(n!=NULL)
{
pnode tmp=new node;
tmp->left = NULL;
tmp->right = NULL;
tmp->data = a;
if(n->data > a )
{
if(n->left != NULL)
InsertNode(n->left, a);
else
n->left = tmp;
}
else
{
if(n->right != NULL)
InsertNode(n->right, a);
else
n->right = tmp;
}
}
}
//构造树
root ConstructTree(int a[], int len)
{
int i;
root r = new node;
r->left = NULL;
r->right = NULL;
if(r!=NULL)
{
if(len>0)
r->data = a[0];
for(i=1;i<len;i++)
{
InsertNode(r,a[i]);
}
return r;
}
return NULL;
}
int main()
{
int a[] = {4,2,6,1,3,5,7};
root r = ConstructTree(a,7);
if(r!=NULL)
printTree(r);
treeToDoubleList(r);
printDoubleList(r);
return 0;
}