zoukankan      html  css  js  c++  java
  • 面试题27:二叉搜索树与双向链表

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

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

    代码实例:

    View Code
    #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\t", pNode->m_nValue);
            pNode = pNode->m_pRight;
        }
        printf("\nPrintList ends.\n");
    }
    
    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");
    }
  • 相关阅读:
    会议室预订系统
    event chrome firefox 获取点击对象的 id 类
    微信支付 301 500 php 7 simplexml_load_string
    会议室预订
    ini_set('date.timezone','Asia/Shanghai');
    UnionID OpenID
    Location 接口表示其链接到的对象的位置
    confirm() event.target.getAttribute('id')
    php 代替 js实现自定义时间选择器
    前端页面 重复提交避免
  • 原文地址:https://www.cnblogs.com/xwdreamer/p/2475300.html
Copyright © 2011-2022 走看看