题目:把二元查找树转变成排序的双向链表
输入一棵二元查找树,将该二元查找树转换成一个排序的双向链表。
要求不能创建任何新的结点,只调整指针的指向。
10
/ \
6 14
/ \ / \
4 8 12 16 转换成双向链表 4=6=8=10=12=14=16。
方案一:
BSTreeNode * treeToLinkedList(BSTreeNode * root)
{
BSTreeNode * head, * tail;
helper(head, tail, root);
return head;
}
//基本思想:函数helper将root子树在中序下的头赋值给head,把尾赋值给tail。函数负责把root和左子树的tail及右子树的head连接。
void helper(BSTreeNode *& head, BSTreeNode *& tail, BSTreeNode *root)
{
BSTreeNode *lt, *rh;
if (root == NULL) //也可使用(root->m_pLeft == NULL && root->m_pRight==NULL){head = root;tail=root;return;}
{
head = NULL, tail = NULL;
return;
}
helper(head, lt, root->m_pLeft);
helper(rh, tail, root->m_pRight);
if (lt!=NULL)
{
lt->m_pRight = root;
root->m_pLeft = lt;
}
else
{
head = root;
}
if (rh!=NULL)
{
root->m_pRight=rh;
rh->m_pLeft = root;
}
else
{
tail = root;
}
}
方案二:
基本思想:设置一个全局变量last表示当前已处理的部分子树的最后一个节点。每次递归调用左子树,直到遇到最左的节点后才开始更新last,而后递归调用右子树。
其实也可以把last做成一个指针参数传给convert函数,它的类型是Node* &last或者Node **last。
Node* head;
Node* last;
void convert(Node* p){
if(p==null)return;
convert(p->left);
addToList(p);
convert(p->right);
}
void addToList(Node* p){
if(last !=null){
p->left = last;
last->right = p;
}
else{
head = p;
}
last = p;
}