把二元查找树转变成排序的双向链表--算法001

来源:互联网 发布:海关数据如何分析 编辑:程序博客网 时间:2024/06/10 08:29
1.把二元查找树转变成排序的双向链表
题目:
输入一棵二元查找树,将该二元查找树转换成一个排序的双向链表。
要求不能创建任何新的结点,只调整指针的指向。
10
/ \
6 14
/ \ / \
4 8 12 16
转换成双向链表
4=6=8=10=12=14=16。
首先我们定义的二元查找树节点的数据结构如下:
struct BSTreeNode
{
int m_nValue; // value of node
BSTreeNode *m_pLeft; // left child of node
BSTreeNode *m_pRight; // right child of node

};

解析: 1:构造二叉查找树;

       2:中序遍历二叉查找树,因此结点按从小到大顺序访问,假设之前访问过的结点已经调整为一个双向链表,那么
         只需要将当前结点连接至双向链表的最后一个结点即可,访问完后,双向链表也就调整完了
(100题中有个递归的解法没有看懂,到网上浏览了一下,找到一个简单易懂的解法,亲自编程下,发现是可行的)
************************************************************************************************************
#include <stdio.h>
#include <iostream>
using namespace std;
struct BSTreeNode
{
    int m_nValue; // value of node
    BSTreeNode *m_pLeft; // left child of node
    BSTreeNode *m_pRight; // right child of node
};
typedef BSTreeNode DoubleList;
DoubleList * pHead;       // 双向链表的头结点
DoubleList * pListIndex;  //
void convertToDoubleList(BSTreeNode * pCurrent);


void addBSTreeNode(BSTreeNode* &pCurrent,int value)
{
 if(pCurrent == NULL)
 {
  BSTreeNode *pBSTree = new BSTreeNode();  // pCurrent为空时需要创建新的节点
  pBSTree->m_nValue = value;
  pBSTree->m_pLeft = NULL;
  pBSTree->m_pRight = NULL;
  pCurrent = pBSTree;
 }
 else
 {
  if((pCurrent->m_nValue)>value)
  {
   addBSTreeNode(pCurrent->m_pLeft,value);
  }
  else if((pCurrent->m_nValue)< value)
  {
   addBSTreeNode(pCurrent->m_pRight,value);
  }
  else
  {
   cout << "请输入不同的数字" <<endl;
  }
 }
}

/************************************************************************/
 
/************************************************************************/
/* 中序遍历二叉树,同时调整结点指针                                                                     */
void ergodicBSTree(BSTreeNode * pCurrent)
{
    if (NULL == pCurrent)
    {        
        return;
    }
    if (NULL != pCurrent->m_pLeft)
    {
        ergodicBSTree(pCurrent->m_pLeft);    
    }

    // 节点接到链表尾部
    convertToDoubleList(pCurrent);

    // 右子树为空
    if (NULL != pCurrent->m_pRight)
    {
        ergodicBSTree(pCurrent->m_pRight);
    }
}

// 二叉树转换成list
void  convertToDoubleList(BSTreeNode * pCurrent)
{
   // 此时pListIndex相当于双向链表的最后一个结点
    pCurrent->m_pLeft = pListIndex;
    if (NULL != pListIndex)
    {
        pListIndex->m_pRight = pCurrent;
    }
    else
    {
        pHead = pCurrent;
    }    
    pListIndex = pCurrent;   // 对于双向链表,标记最后一个结点
    cout<<pCurrent->m_nValue<<endl;
}
/************************************************************************/
int _tmain(int argc, _TCHAR* argv[])
{
    BSTreeNode * pRoot = NULL;
    pListIndex = NULL;
    pHead = NULL;
    addBSTreeNode(pRoot, 10);
    addBSTreeNode(pRoot, 4);
    addBSTreeNode(pRoot, 6);
    addBSTreeNode(pRoot, 8);
    addBSTreeNode(pRoot, 12);
    addBSTreeNode(pRoot, 14);
    addBSTreeNode(pRoot, 15);
    addBSTreeNode(pRoot, 16);
    ergodicBSTree(pRoot);


// 输出双向链表的值
BSTreeNode * pCurrent = pHead;
do
{
cout<<pCurrent->m_nValue<<" ";;
pCurrent = pCurrent->m_pRight;
}while(pCurrent != NULL);

int n=0;
cin>>n;
    return 0;

}
***********************************************************************************************************************

之前笔试屡获惨败,都是在纸上写程序的能力太差,解题的速度太慢,C++没有掌握。导致很多好的公司去不了。这次要多加练习。

1、练习C++

2、多做算法题,多练习在纸上写清楚明白