• 二叉搜索树转双向链表


    题目:输入一棵二叉搜索树,将该二叉搜索树转换成一个排序的双向链表。要求不能创建任何新的结点,只能调整树中结点指针的指向。比如输入下图中左边儿茶搜索树,则输出转换后的排序双向链表。
         10
        /  
       6    14
      /    / 
     4   8 12 16
    4=6=8=10=12=14=16


     将二叉搜索树转化为有序双向链表,类似于中序遍历,中序遍历的结果就是一个排序的数字。因此在程序中以中序遍历树,当遍历左子树到在叶子结点的时候,开始修改指针。 


    #include<iostream>
    #include<stdlib.h>
    using namespace std;
    
    struct BinaryTreeNode
    {
        int m_nValue;
        BinaryTreeNode* m_pLeft;
        BinaryTreeNode* m_pRight;
    };
    
    //创建二叉树结点
    BinaryTreeNode* CreateBinaryTreeNode(int value)
    {
        BinaryTreeNode* pNode=new BinaryTreeNode();
        pNode->m_nValue=value;
        pNode->m_pLeft=NULL;
        pNode->m_pRight=NULL;
        return pNode;
    }
    
    void ConnectTreeNodes(BinaryTreeNode* pParent,BinaryTreeNode* pLeft,BinaryTreeNode* pRight)
    {
        if(pParent!=NULL)
        {
            pParent->m_pLeft=pLeft;
            pParent->m_pRight=pRight;
        }
    }
    
    void InOrderPrintTree(BinaryTreeNode* pRoot)//中序遍历
    {
        if(pRoot!=NULL)
        {
            if(pRoot->m_pLeft!=NULL)//
                InOrderPrintTree(pRoot->m_pLeft);
    
            cout<<"value of this node is "<<pRoot->m_nValue<<endl;
    
            if(pRoot->m_pRight!=NULL)
                InOrderPrintTree(pRoot->m_pRight);
        }
        else
        {
            cout<<"this node is null."<<endl;
        }
    
    }
    
    void Convert(BinaryTreeNode* pNode,BinaryTreeNode** pLastNodeInList)
    {
        if(pNode==NULL)
            return;
    
        BinaryTreeNode* pCurrent=pNode;
        //左子树转换,遍历到左子树的叶子结点
        if(pCurrent->m_pLeft!=NULL)//遍历左子树
            Convert(pCurrent->m_pLeft,pLastNodeInList);
    
        pCurrent->m_pLeft=*pLastNodeInList;
        if((*pLastNodeInList)!=NULL)
            (*pLastNodeInList)->m_pRight=pCurrent;
    
        *pLastNodeInList=pCurrent;
        //右子树转换
        if(pCurrent->m_pRight!=NULL)//遍历右子树
            Convert(pCurrent->m_pRight,pLastNodeInList);
    
    }
    
    BinaryTreeNode* Convert(BinaryTreeNode* pRoot)
    {
        BinaryTreeNode* pLastNodeInList=NULL;//指向双向链表的尾结点
        Convert(pRoot,&pLastNodeInList);//转换排序二叉树为双向链表
    
        //求双向链表的头结点
        BinaryTreeNode* pHeadOfList=pLastNodeInList;
        while(pHeadOfList!=NULL&&pHeadOfList->m_pLeft!=NULL)
            pHeadOfList=pHeadOfList->m_pLeft;
        return pHeadOfList;
    
    }
    
    //输出双向链表
    void PrintList(BinaryTreeNode* pRoot)
    {
        BinaryTreeNode* pNode = pRoot;
        while(pNode != NULL)
        {
            printf("%d	", pNode->m_nValue);
            pNode = pNode->m_pRight;
        }
        printf("
    PrintList ends.
    ");
    }
    
    void main()
    {
    //            10
    //         /      
    //        6        14
    //       /        /
    //      4  8     12  16
        //创建树结点
        BinaryTreeNode* pNode10 = CreateBinaryTreeNode(10);
        BinaryTreeNode* pNode6 = CreateBinaryTreeNode(6);
        BinaryTreeNode* pNode14 = CreateBinaryTreeNode(14);
        BinaryTreeNode* pNode4 = CreateBinaryTreeNode(4);
        BinaryTreeNode* pNode8 = CreateBinaryTreeNode(8);
        BinaryTreeNode* pNode12 = CreateBinaryTreeNode(12);
        BinaryTreeNode* pNode16 = CreateBinaryTreeNode(16);
        //连接树结点
        ConnectTreeNodes(pNode10, pNode6, pNode14);
        ConnectTreeNodes(pNode6, pNode4, pNode8);
        ConnectTreeNodes(pNode14, pNode12, pNode16);
    
        //PrintTree(pNode10);
        InOrderPrintTree(pNode10);//中序遍历
        BinaryTreeNode* pHeadOfList=Convert(pNode10);//获取双向链表头结点
        PrintList(pHeadOfList);//输出链表
    
        system("pause");
    }
  • 相关阅读:
    第一行代码--笔记(1)
    iOS UITableView深入
    iOS 数据库主键重复,依然可以插入
    UILabel文本高度自适应 不同系统出现问题
    UIlabel上的文字 距上 居左 对齐
    UILabel 自定义字体
    【整理】--VC 编译整理
    【整理】--【内核模块】简单例子,编译加载
    【原创】-- uboot,kennel,fs,rootfs 编译制作
    【原创】-- nfs安装配置及使用,挂载根文件系统
  • 原文地址:https://www.cnblogs.com/bendantuohai/p/4532530.html
Copyright © 2020-2023  润新知