zoukankan      html  css  js  c++  java
  • 二叉搜索树与双向链表的转换

    题目:输入一棵二叉搜索树(记住是搜索树),将该二叉搜索树转换为一个排序的双向链表。要求:不能创建任何新的结点,只能调整树中结点指针的指向。

    分析:如下图

    image

    因为是二叉搜索树。所以树的排列是规则的。通过中序遍历正好遍历的是由小到大的序列。

    要求说明是只能改变树结点指针的指向,不能增加新的空间和结点。所以在中序遍历的时候,主要是遍历到结点后就去改变指针指向。

    为了简单,采用递归进行遍历。

    树的结构

    struct BinaryTreeNode{
        int m_data;
        BinaryTreeNode* m_LeftNode;
        BinaryTreeNode* m_RightNode;
    };

    下面这部分代码是总体框架

    BinaryTreeNode* TransTreeToList(BinaryTreeNode* pBinaryTree)
    {
        if (pBinaryTree == NULL)
            return NULL;
        BinaryTreeNode *pLastNodeInList = NULL;
        TransTreeToList(pBinaryTree, &pLastNodeInList);    //pLastNodeInList指向双向链表的尾结点
        //找到链表的头结点
        BinaryTreeNode* pHeadNode = pLastNodeInList;
        if (pHeadNode == NULL)
            return;
        while (pHeadNode->m_LeftNode != NULL)
            pHeadNode = pHeadNode->m_LeftNode;
    }

    下面部分代码是详细的设计

    void TransTreeToList(BinaryTreeNode* pNode, BinaryTreeNode** pLastNodeInList)
    {
        if (pNode == NULL)
            return;
        BinaryTreeNode* pCurrent = pNode;                                  //根节点
        //下面所有代码是采用中序遍历的递归方法,仅仅不同的只是每次递归都将pLastNodeInList放到链表的最左边。
        if (pCurrent->m_LeftNode != NULL)                                  //找到最左子树
            TransTreeToList(pCurrent->m_LeftNode, pLastNodeInList);
        //下面三行代码表示将pLastNodeInList加到最左边
        pCurrent->m_LeftNode = *pLastNodeInList;                      
        if (*pLastNodeInList != NULL)
            (*pLastNodeInList)->m_RightNode = pCurrent;                    //因为是双向链表,所以pLastNodeInList要向右指向当前结点
    
        *pLastNodeInList = pCurrent;                                       //再遍历根节点,此时*pLastNodeInList为根节点,也就是在没有遍历右子树之前最后的一个结点。
    
        if(pCurrent->m_RightNode != NULL)                                  //再遍历右子树
            TransTreeToList(pCurrent->m_RightNode,pLastNodeInList);
    }

    代码简单分析:

    总体的步骤还是采用中序递归遍历。先遍历左边结点,接着将左边结点加到根节点的最左边,变成双向指针。接下来pLastNodeInList指向链表的最右边。接下来再遍历右子树,将pLastNodeInList加到右子树的最左边,这样递归下去。

    总之要明白整个代码是按照中序递归遍历的,过程中仅仅就是改变了指针方向。不要过分追究过程细节。

    时间复杂度分析:

    该算法首先从根要点一直向左走,找到最左边的结点,其时间复杂度为O(logN),然后对二叉排序树中的每个结点遍历一次,进行指针变换,其时间复杂度为O(N),所以总的时间复杂度为O(N)

    参考:http://blog.csdn.net/ljianhui/article/details/22338405

           剑指offer

    void TransTree2List(Tree *pTree)
    {
    	if( NULL == pTree )
    		return ;
        TransTree2List(pTree->leftTree);
        Convert2List(pTree);
        TransTree2List(pTree->rightTree);
    }
    
    Tree *pHead = NULL;
    Tree *pIndex = NULL ;
    void Convert2List(Tree *pTreeNode)
    {
        pIndex = pTreeNode->leftTree ;
        if (NULL == pIndex)
        	pHead = pTreeNode ;
        else
        	pIndex->rightTree = pTreeNode;
        pHead = pTreeNode ;
    }
    

      

  • 相关阅读:
    jmeter如何引用自己编写的java文件编译的jar包
    Vue+Django REST framework 打造生鲜电商项目(学习笔记二)
    mysql笔试题
    面试遇到的问题
    Idea中maven项目pom文件中已引入testng但项目文件中无法引入@Test
    记录一次TestNg+MyBatis中的SqlSession出现的问题,问题虽然解决了但尚未明白问题原因
    PyMySQL的基本操作
    MySQL循环语句
    Vue父子组件和非父子组件间的通信
    Python的静态方法和类成员方法
  • 原文地址:https://www.cnblogs.com/menghuizuotian/p/3799587.html
Copyright © 2011-2022 走看看