![2526751c5a084684266c37fce5089505.png](https://i-blog.csdnimg.cn/blog_migrate/ed9967f02393a3092437ca466a8c1bb9.jpeg)
//面试题36.二叉搜索树与双向链表
//题目:输入一棵二叉搜索树,将该二叉搜索树转换成一个排序的双向链表。
//要求不能创建任何新的节点,只能调整树中结点指针的指向。比如,输入图4.15中左边的二叉搜索树,
//输出转换之后的排序双向链表。二叉搜索树的节点定义如下:
/*
struct BinaryTreeNode
{
int m_nValue;
BinaryTreeNode* m_pLeft;
BinaryTreeNode* m_pRight;
};
*/
/*
图4.15
二叉搜索树如下:
10
6 14
4 8 12 16
输出的排序双向链表如下:
4 <=> 6 <=> 8 <=> 10 <=> 12 <=> 14 <=>16
*/
/*
思路:
二叉搜索树的特点是,所有左子节点 < 根结点,所有右子节点 > 根结点。针对题目中要求的排序的双向链表,对二叉树可以采用中序遍历。
对于中序遍历可以将树分为三部分,第一部分是左子树,即上述的4 <=> 6 <=> 8,根结点10,右子树12 <=> 14 <=>16。把左右子树都转换成双向链表之后,再将左子树
中最大的节点(8)与根结点连接起来,将右子树中最小的节点(12)与根结点连接起来,整棵二叉搜索树便转换称为一个排序的双向链表。
对于左右子树的转换,可以采用递归。
*/
#include<iostream>
#include"binarytreen.h"
using namespace std;
void ConvertNode(BinaryTreeNode*pNode, BinaryTreeNode**pLastNodeInList);
BinaryTreeNode* Convert(BinaryTreeNode*pRoot)
{
BinaryTreeNode*pLastNodeInList = nullptr;//pLastNodeInList 指的是已经转换好的链表的最后的一个节点
ConvertNode(pRoot, &pLastNodeInList);
//pLastNodeInList 指的是已经转换好的链表的最后的一个节点
BinaryTreeNode*pHeadOfList = pLastNodeInList;
while (pHeadOfList != nullptr&&pHeadOfList->m_pLeft != nullptr)//我们需要返回头节点
pHeadOfList = pHeadOfList->m_pLeft;
return pHeadOfList;
}
void ConvertNode(BinaryTreeNode*pNode, BinaryTreeNode**pLastNodeInList)
{
if (pNode == nullptr)
return;
BinaryTreeNode*pCurrent = pNode;//传入根结点
//1、递归转换左子树
if (pCurrent->m_pLeft != nullptr)
ConvertNode(pCurrent->m_pLeft, pLastNodeInList);
//2、将转换好的左子树的最后一个节点*pLastNodeInList与根结点连接,注意连接是个双向的,因为要求转换的是双向链表
pCurrent->m_pLeft = *pLastNodeInList;//根结点的左指针,指向左子树的最后一个节点*pLastNodeInList
if (*pLastNodeInList != nullptr)
(*pLastNodeInList)->m_pRight = pCurrent; //左子树的最后一个节点*pLastNodeInList的右指针,指向根结点
//3、递归转换右子树
*pLastNodeInList = pCurrent;
if (pCurrent->m_pRight != nullptr)//递归转换右子树
ConvertNode(pCurrent->m_pRight, pLastNodeInList);
}
//===================测试代码=========================
void PrintDoubleLinkedList(BinaryTreeNode*pHeadOfList)
{
BinaryTreeNode*pNode = pHeadOfList;
printf("The nodes from left to right are:n");
while (pNode != nullptr)
{
printf("%d t", pNode->m_nValue);
if (pNode->m_pRight == nullptr)
break;
pNode = pNode->m_pRight;
}
printf("The nodes from right to left are:n");
while (pNode != nullptr)
{
printf("%d t", pNode->m_nValue);
if (pNode->m_pLeft == nullptr)
break;
pNode = pNode->m_pLeft;
}
printf("n");
}
void DestroyList(BinaryTreeNode*pHeadOfList)
{
BinaryTreeNode*pNode = pHeadOfList;
while (pNode != nullptr)
{
BinaryTreeNode*pNext = pNode->m_pRight;
delete pNode;
pNode = pNext;
}
}
void Test(const char*testname,BinaryTreeNode*pRoot)
{
if (testname != nullptr)
printf("%s begins:n", testname);
PrintTree(pRoot);
BinaryTreeNode*pHeadOfList = Convert(pRoot);
PrintDoubleLinkedList(pHeadOfList);
}
// 10
// 6 14
//4 8 12 16
void Test01()
{
BinaryTreeNode*pNode10 = CreatNode(10);
BinaryTreeNode*pNode6 = CreatNode(6);
BinaryTreeNode*pNode14 = CreatNode(14);
BinaryTreeNode*pNode4 = CreatNode(4);
BinaryTreeNode*pNode8 = CreatNode(8);
BinaryTreeNode*pNode12 = CreatNode(12);
BinaryTreeNode*pNode16 = CreatNode(16);
BuildTree(pNode10, pNode6, pNode14);
BuildTree(pNode6, pNode4, pNode8);
BuildTree(pNode14, pNode12, pNode16);
Test("Test01", pNode10);
DestroyList(pNode10);
//DestroyTree(pNode10);
}
// 10
// 6
// 4
void Test02()
{
BinaryTreeNode*pNode10 = CreatNode(10);
BinaryTreeNode*pNode6 = CreatNode(6);
BinaryTreeNode*pNode4 = CreatNode(4);
BuildTree(pNode10, pNode6, nullptr);
BuildTree(pNode6, pNode4, nullptr);
Test("Test02", pNode10);
DestroyList(pNode10);
//DestroyTree(pNode10);
}
// 10
// 6
// 4
void Test03()
{
BinaryTreeNode*pNode10 = CreatNode(10);
BinaryTreeNode*pNode6 = CreatNode(6);
BinaryTreeNode*pNode4 = CreatNode(4);
BuildTree(pNode10, nullptr, pNode6);
BuildTree(pNode6, nullptr, pNode4);
Test("Test03", pNode10);
DestroyList(pNode10);
//DestroyTree(pNode10);
}
// 10
void Test04()
{
BinaryTreeNode*pNode10 = CreatNode(10);
BuildTree(pNode10, nullptr, nullptr);
Test("Test04", pNode10);
DestroyList(pNode10);
//DestroyTree(pNode10);
}
// nullptr
void Test05()
{
Test("Test05", nullptr);
}
int main()
{
//Test01();
//Test02();
//Test03();
Test04();
//Test05();
system("pause");
return 0;
}
//=========binarytree.h================
#pragma once
struct BinaryTreeNode
{
int m_nValue;
BinaryTreeNode* m_pLeft;
BinaryTreeNode* m_pRight;
};
BinaryTreeNode* CreatNode(int value);
void BuildTree(BinaryTreeNode*pRoot, BinaryTreeNode*pLeft, BinaryTreeNode*pRight);
void PrintTree(BinaryTreeNode*pRoot);
void DestroyTree(BinaryTreeNode*pRoot);
//==========binarytree.cpp===============
#include"binarytreen.h"
#include<iostream>
BinaryTreeNode* CreatNode(int value)
{
BinaryTreeNode*pNode = new BinaryTreeNode();
pNode->m_nValue = value;
pNode->m_pLeft = nullptr;
pNode->m_pRight = nullptr;
return pNode;
}
void BuildTree(BinaryTreeNode*pRoot, BinaryTreeNode*pLeft, BinaryTreeNode*pRight)
{
if (pRoot != nullptr)
{
pRoot->m_pLeft = pLeft;
pRoot->m_pRight = pRight;
}
}
void PrintTree(BinaryTreeNode*pRoot)
{
BinaryTreeNode*pNode = pRoot;
if (pNode == nullptr)
return;
else
printf("This node value is: %dn", pNode->m_nValue);
PrintTree(pNode->m_pLeft);
PrintTree(pNode->m_pRight);
}
void DestroyTree(BinaryTreeNode*pRoot)
{
if (pRoot == nullptr)
return;
if(pRoot->m_pLeft!=nullptr)
DestroyTree(pRoot->m_pLeft);
if(pRoot->m_pRight!=nullptr)
DestroyTree(pRoot->m_pRight);
delete pRoot;
pRoot = nullptr;
}