网上看到的笔试题一道:
输入一棵二元查找树,将该二元查找树转换成一个排序的双向链表。要求不能创建任何新的结点,只能调整指针的指向,如:
10
/ \
6 14
/ \ / \
4 8 12 16
转换后成双向链表4<>6<>8<>10<>12<>14<>16。
写了一个递归算法如下:
#include <iostream>
using namespace std;
typedef struct Node
{
Node() : v(0), left(NULL), right(NULL) {}
Node(int _v, Node *l=NULL, Node *r=NULL) : v(_v), left(l), right(r) {}
int v;
Node *left;
Node *right;
}sNode;
//LB_c: 注意这里的参数head, tail是指针的引用,或者可以用二级指针。
//局部变量l_tail和r_head分别记录左子树的最后一个节点和右子树的第一个节点。
void changeToList(sNode *root, sNode *&head, sNode *&tail)
{
if (NULL == root)
{
head = NULL;
tail = NULL;
return;
}
sNode *l_tail, *r_head;
changeToList(root->left, head, l_tail);
changeToList(root->right, r_head, tail);
if (l_tail != NULL)
{
root->left = l_tail;
l_tail->right = root;
}
else
{
head = root;
}
if (r_head != NULL)
{
root->right = r_head;
r_head->left = root;
}
else
{
tail = root;
}
}
int main()
{
//create BST
sNode n1(4);
sNode n2(8);
sNode n3(6, &n1, &n2);
sNode n4(12);
sNode n5(16);
sNode n6(14, &n4, &n5);
sNode root(10, &n3, &n6);
//call changeToList()
sNode *pHead, *pTail;
changeToList(&root, pHead, pTail);
//output the doubly-linked list
sNode *pTemp = pHead;
while (pTemp != NULL)
{
cout << pTemp->v << " => ";
pTemp = pTemp->right;
}
cout << endl;
return 0;
}