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

来源:互联网 发布:linux apache压力测试 编辑:程序博客网 时间:2024/05/15 10:24

这是一道面试题,将 二叉搜索树  ->  排序双向链表, 虽然是一道面试题, 不过也给我们提供了一种思路, 二叉搜索树和双向链表这两种我们常用的数据结构, 他们之间可以进行互相转换吗?  倒也是一个值得玩味的想法。


思路:根据 二叉搜索树 的性质,要转换为 有序双向链表, 则, 中序遍历最适合。  因为中序遍历出来是有序的,由小到大。

二叉搜索树每个节点有两个指针分别指向左右两个孩子, 双向链表每个结点有两个指针分别指向前一个结点和后一个结点。如图:


我们需要将如左图的二叉搜索树 转换为 右下角的 有序双向链表。






我们给出实现代码:

//将二叉搜索树->排序双向链表,不能创建任何新节点,只能调整树中结点指针的指向.//思路:根据 二叉搜索树 的性质,要转换为 有序双向链表, 则, 中序遍历最适合。  因为中序遍历出来是有序的,由小到大。//二叉搜索树每个节点有两个指针分别指向左右两个孩子, 双向链表每个结点有两个指针分别指向前一个结点和后一个结点, 如图。#include <iostream>#include <windows.h>using namespace std;//定义二叉搜索树结点结构struct BSTNode{      BSTNode* _left;      BSTNode* _right;      int _data;  BSTNode( int data, BSTNode* left = NULL, BSTNode* right = NULL ): _data( data ), _left( left ), _right( right ){}};  //插入新结点到树中void Insert( BSTNode*& tree, int data );  //将二叉搜索树tree转化成双向链表,并返回头结点  BSTNode* BSTreeToList( BSTNode* tree );//遍历二叉搜索树tree的各个结点,并进行指针调整  void ConvertNode( BSTNode* tree, BSTNode*& lastNodeInList );  //查找二叉搜索树tree的最左结点  BSTNode* FindLeftmostNode( BSTNode* tree );//以中序遍历打印二叉搜索树tree  void PrintBiTree( BSTNode* tree );  //打印链表  void PrintList( BSTNode* headOfList );     void Insert( BSTNode*& tree, int data )  {  if ( NULL == tree ){tree = new BSTNode( data, NULL, NULL );}else if ( data < tree->_data ){Insert( tree->_left, data );}else if ( data > tree->_data ){Insert( tree->_right, data );}else{return;}}  BSTNode* BSTreeToList( BSTNode* tree )  {      if ( NULL == tree ){        return NULL;  }    //找到最左边的结点,即转换后链表的头结点  BSTNode* headOfList = FindLeftmostNode( tree );    BSTNode* lastNodeInList = NULL;      //进行转换      ConvertNode( tree, lastNodeInList );    return headOfList; }  BSTNode* FindLeftmostNode( BSTNode* tree )  {  if ( NULL == tree ){return NULL;}while ( NULL != tree->_left ){tree = tree->_left;}return tree;}  void ConvertNode( BSTNode* tree, BSTNode*& lastNodeInList )  {      if ( NULL == tree ){        return;  }    //对tree的左子树进行转换,lastNodeInList是转换后链表中最后一个结点的指针  if ( NULL != tree->_left ){        ConvertNode( tree->_left, lastNodeInList );  }    //调整tree的left指针,指向上一个结点      tree->_left = lastNodeInList;      //调整最后一个结点指针的指向,使它的 right 指向下一个结点(即此时的结点tree)      if ( NULL != lastNodeInList ){        lastNodeInList->_right = tree;}    //调整指向最后链表一个结点的指针      lastNodeInList = tree;      //对tree的右子树进行转换,lastNodeInList是转换后链表最后一个结点的指针  if ( NULL != tree->_right ){        ConvertNode( tree->_right, lastNodeInList );  }}void PrintBSTree( BSTNode* tree )  {  if ( NULL == tree ){return;}PrintBSTree( tree->_left );cout << tree->_data << " ";PrintBSTree( tree->_right );}  void PrintList( BSTNode* headOfList )  {  if ( NULL == headOfList ){return;}BSTNode* node = headOfList;while ( NULL != node ){cout << node->_data << " ";node = node->_right; }cout << endl;}  int main()  {      BSTNode* tree = NULL;int a[] = { 626, 1226, 521, 100, 600, 80, 110 };    for ( size_t i = 0; i < (sizeof(a) / sizeof( a[0] )); ++i )      {  Insert( tree, a[i] );    }    PrintBSTree(tree);  cout << endl;    //进行转换      BSTNode* headOfList = BSTreeToList( tree );      PrintList( headOfList );  system( "pause" );    return 0;  }  


2 0