问题:对于输入的一棵二叉查找树,将该二叉查找树转换成一个排序的双向链表,要求不能创建任何新的结点,只调整指针的指向来达到目的。
目测这个问题不难解决,应该可以在O(n)的时间复杂度内解决。对于一个二叉查找树,转换为一个从小到大排序的链表,那么根节点的左儿子及其子孙都会在根节点的前面,根节点的右儿子及其子孙都会在根节点的后面。这样,一个递归的算法便可以解决问题。按照这个思路我把代码写了出来,验证结果没有问题。
行28-70的代码就是完成转换的方法,vlr是包含两个指针的数组,vlr[0]指向root这棵树转换完后的链表头,vlr[1]指向链表尾。
#include <iostream>
#include <string>
using namespace std;
struct tree {
int value;
struct tree *lchild;
struct tree *rchild;
};
struct tree *insert(struct tree *root, int value)
{
if (root) {
if (value < root->value) {
root->lchild = insert(root->lchild, value);
} else {
root->rchild = insert(root->rchild, value);
}
} else {
root = new struct tree;
root->value = value;
root->lchild = 0;
root->rchild = 0;
}
return root;
}
struct tree *convert_tree(struct tree *root, struct tree *vlr[2])
{
if (root) {
struct tree *lrl[2] = {0, 0}, *lrr[2] = {0, 0};
convert_tree(root->lchild, lrl);
convert_tree(root->rchild, lrr);
if (lrl[0]) {
if (lrr[0]) {
vlr[0] = lrl[0];
vlr[1] = lrr[1];
root->lchild = lrl[1];
root->rchild = lrr[0];
lrl[0]->lchild = lrr[1];
lrl[1]->rchild = root;
lrr[0]->lchild = root;
lrr[1]->rchild = lrl[0];
} else {
vlr[0] = lrl[0];
vlr[1] = root;
root->lchild = lrl[1];
root->rchild = lrl[0];
lrl[0]->lchild = root;
lrl[1]->rchild = root;
}
} else {
if (lrr[0]) {
vlr[0] = root;
vlr[1] = lrr[1];
root->lchild = lrr[1];
root->rchild = lrr[0];
lrr[0]->lchild = root;
lrr[1]->rchild = root;
} else {
vlr[0] = root;
vlr[1] = root;
root->lchild = root;
root->rchild = root;
}
}
root = vlr[0];
}
return root;
}
struct tree *convert(struct tree *root)
{
struct tree *list[2] = {0, 0};
return convert_tree(root, list);
}
void print_tree_prefix(struct tree *root, string pfx)
{
if (root) {
if (root->lchild) {
cout << pfx << "|" << endl;
if (root->rchild)
cout << pfx << "|-<L> " << root->lchild->value << endl;
else
cout << pfx << "`-<L> " << root->lchild->value << endl;
print_tree_prefix(root->lchild, pfx + "| ");
}
if (root->rchild) {
cout << pfx << "|" << endl;
cout << pfx << "`-<R> " << root->rchild->value << endl;
print_tree_prefix(root->rchild, pfx + " ");
}
}
}
void print_tree(struct tree *root)
{
if (root) {
cout << root->value << endl;
print_tree_prefix(root, "");
}
}
void print_list(struct tree *root)
{
struct tree *next = root;
if (next) {
cout << "list : ";
do {
cout << next->value;
next = next->rchild;
if (next != root)
cout << " <-> ";
} while (next != root);
cout << "." << endl;
}
}
int main()
{
struct tree *root = 0;
root = insert(root, 100);
root = insert(root, 233);
root = insert(root, 33);
root = insert(root, 67);
root = insert(root, 104);
root = insert(root, 34);
root = insert(root, 32);
root = insert(root, 766);
root = insert(root, 456);
print_tree(root);
root = convert(root);
print_list(root);
return 0;
}
100
|
|-<L> 33
| |
| |-<L> 32
| |
| `-<R> 67
| |
| `-<L> 34
|
`-<R> 233
|
|-<L> 104
|
`-<R> 766
|
`-<L> 456
对于这样一棵树,输出的结果为
list : 32 <-> 33 <-> 34 <-> 67 <-> 100 <-> 104 <-> 233 <-> 456 <-> 766.