二叉搜索树转化为双向链表

来源:互联网 发布:淘宝赌石最好赌出什么 编辑:程序博客网 时间:2024/04/29 13:02

题意:给定一棵二叉搜索树,将该二叉搜索树转化为一个排序的双向链表,要求只能调整树中节点指针的指向

分析:对二叉搜索树进行中序遍历,得到的序列就是有序的,如果在中序遍历的同时改变指针的指向,当中序遍历完成之后,就可以得到一个有序的双向链表。

            按照上面的分析,将一棵二叉搜索树分为三部分,根节点(root),左子树(lchild),右子树(rchild),根据所需链表的需求,root节点应该跟lchild中节点最大的值相连,同时root节点还需要跟rchild中节点最小的值相连。当root节点跟lchild中节点的最大值相连时,lchild已被转化为一个有序的双向链表,然后再将root节点跟lchild连接起来,此时新的有序链表的长度就增加1了,之后再去遍历转换rchild,再将root节点和rchild中的最小值节点连接起来,对lchild、rchild的转换采用递归的方法。

核心:由于所采用的是中序遍历的方式,即采用下面的这种模式

void InOrder(BiTree pNode){    if(NULL == pNode)        return;    InOrder(pNode->lchild);    //.....processing    InOrder(pNode->rchild);}

那么processing这部分应该怎么处理,从上面的分析可知这一步用来将root节点跟已经得到的有序双向链表连接起来,即有序双向链表的最后一个节点和root连接要互联,之后root节点就成为了有序双向链表的最后一个节点,然后在继续递归处理。

二叉树的定义参加二叉树的定义

具体的实现参见下面的代码:

#include "Binary.h"void BiTreeToDLinkList(BiTree pRoot, BiTree *pLastNodeInList){    if(NULL == pRoot)        return;    //递归左子树    if(pRoot->lchild)        BiTreeToDLinkList(pRoot->lchild, pLastNodeInList);    //假设左子树已递归完成,左子树此时已是一个双向链表,*pLastNodeInList指向链表的最后一个节点,现在就需要完成当前节点和链接最后一个节点的链接工作,即pRoot与*pLastNodeInList的链接,在链接完成后不要忘记改当前链表的最后一个节点    pRoot->lchild = (*pLastNodeInList);    if((*pLastNodeInList) != NULL)        (*pLastNodeInList)->rchild = pRoot;    (*pLastNodeInList) = pRoot;    //递归右子树    if(pRoot->rchild)        BiTreeToDLinkList(pRoot->rchild, pLastNodeInList);}void ConvertTreeToLinkList(BiTree *pRoot){    if(NULL == *pRoot)        return;    BiTree pLastNodeInList = NULL;    BiTreeToDLinkList(*pRoot, &pLastNodeInList);    //完成转换之后得到的是链表的最后一个节点,现在通过最后一个节点,得到链表的头节点    (*pRoot) = pLastNodeInList;    while((*pRoot)->lchild != NULL)    {        *pRoot = (*pRoot)->lchild;    }}void PrintDLinkList(BiTree pRoot){    if(NULL == pRoot)    {        cout << "根节点为空,请输入有效数据" << endl;        return;    }    BiTree p = pRoot;    cout << "The nodes from left to right are:" << endl;    while(p)    {        cout << p->data << "\t";        if(NULL == p->rchild)            break;        p = p->rchild;    }    cout << endl;    //上面的循环跳出时,p指向链表的最后一个节点    cout << "The nodes from right to left are:" << endl;    while(p)    {        cout << p->data << "\t";        if(NULL == p->lchild)            break;        p = p->lchild;    }    cout << endl;}void Test(BiTree pRoot){    ConvertTreeToLinkList(&pRoot);    PrintDLinkList(pRoot);}void Test1(){    BiTree pNode10 = NULL;    CreateBinaryTreeNode(&pNode10,10);    BiTree pNode6 = NULL;    CreateBinaryTreeNode(&pNode6,6);    BiTree pNode14 = NULL;    CreateBinaryTreeNode(&pNode14,14);    BiTree pNode4 = NULL;    CreateBinaryTreeNode(&pNode4,4);    BiTree pNode8 = NULL;    CreateBinaryTreeNode(&pNode8,8);    BiTree pNode12 = NULL;    CreateBinaryTreeNode(&pNode12,12);    BiTree pNode16 = NULL;    CreateBinaryTreeNode(&pNode16,16);    ConnectTreeNodes(pNode10, pNode6, pNode14);    ConnectTreeNodes(pNode6, pNode4, pNode8);    ConnectTreeNodes(pNode14, pNode12, pNode16);    Test(pNode10);}int main(){    Test1();    return 0;}


   

0 0
原创粉丝点击