問題:對於輸入的一棵二叉查找樹,將該二叉查找樹轉換成一個排序的雙向鏈表,要求不能創建任何新的結點,只調整指針的指向來達到目的。
目測這個問題不難解決,應該可以在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.