题目:
输入一颗二叉搜索树,将该二叉搜索树转换成一个排序的双向链表。要求不能创建任何新的节点,只能调整树中节点指针的方向:
分析:
1:由于要求链表是有序的,可以借助二叉树中序遍历,因为中序遍历算法的特点就是从小到大访问结点。当遍历访问到根结点时,假设根结点的左侧已经处理好,只需将根结点与上次访问的最近结点(左子树中最大值结点)的指针连接好即可。进而更新当前链表的最后一个结点指针。
2:由于中序遍历过程正好是转换成链表的过程,即可采用递归处理
代码:
// BT.cpp : 定义控制台应用程序的入口点。
//
#include "stdafx.h"
#include <iostream>
#include <math.h>
#include <queue>
using namespace std;
//节点的数据结构
class BTree
{
public:
int m_nValue;
BTree* m_nLeft;
BTree* m_nRight;
public:
BTree(int value)
{
m_nValue = value;
}
};
//二叉树的插入实现
void Insert(int value, BTree* &root)
{
if (root == NULL)
{
root = new BTree(value);
}
else if(value < root->m_nValue)
Insert(value,root->m_nLeft);
else if(value > root->m_nValue)
Insert(value,root->m_nRight);
else
;
}
//利用中序遍历把搜索二叉树进行遍历,同时进行转换为双向链表
void ConvertNode(BTree* pRoot,BTree* &pLastNodeInList)
{
if (pRoot == NULL)
return;
BTree* pCurrentNode = pRoot;
if (pCurrentNode->m_nLeft != NULL)//先遍历左子树
{
ConvertNode(pCurrentNode->m_nLeft,pLastNodeInList);
}
/*
处理当前节点与已经遍历链表节点的链接
*/
pCurrentNode->m_nLeft = pLastNodeInList;
if (pLastNodeInList != NULL)//如果pLastNodeInList已经不为空,那么让他的next节点指向当前的节点(right相当于 next)
pLastNodeInList->m_nRight = pCurrentNode;
pLastNodeInList = pCurrentNode;//然后再把pLastNodeInList指向当前的节点
if (pCurrentNode->m_nRight != NULL)//再遍历右子树
{
ConvertNode(pCurrentNode->m_nRight,pLastNodeInList);
}
}
BTree* Convert(BTree* pRoot)
{
BTree* pLastNodeInList = NULL;//指向双链表的尾巴节点
ConvertNode(pRoot,pLastNodeInList);
//转换完毕后,pLastNodeInList指向双向链表的尾巴节点
//我们需要返回头结点
BTree* pHeadOfList = pLastNodeInList;
//头结点先指向尾巴节点,从尾巴节点开始遍历
while (pHeadOfList!= NULL && pHeadOfList->m_nLeft != NULL)
{
pHeadOfList = pHeadOfList->m_nLeft;
}
return pHeadOfList;//返回头节点
}
void PrintInPrev(BTree* pRoot)
{
if(pRoot == NULL)
return;
PrintInPrev(pRoot->m_nLeft);
cout<<pRoot->m_nValue<<" ";
PrintInPrev(pRoot->m_nRight);
}
void PrintList(BTree* &t)
{
if(t == NULL)
return;
while (t != NULL)
{
cout<<t->m_nValue<<" ";
t = t->m_nRight;
}
}
int _tmain(int argc, _TCHAR* argv[])
{
BTree* m_pRoot = new BTree(7);
Insert(3,m_pRoot);
Insert(6,m_pRoot);
Insert(1,m_pRoot);
Insert(2,m_pRoot);
Insert(5,m_pRoot);
Insert(8,m_pRoot);
Insert(7,m_pRoot);
Insert(10,m_pRoot);
PrintInPrev(m_pRoot);
BTree* p = Convert(m_pRoot);
cout<<endl<<"链表:"<<endl;
PrintList(p);
getchar();
return 0;
}