题目:
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
};
分析:
我们看一下上面画出来的这个二叉查找树,发现如果把节点都投影,然后修改左右指针,就可以实现变成双向的链表,我们知道中序遍历是先左子树,在中间节点,然后再右子树,那么我们只要在遍利左子树的时候,用pre记下左子树的最后一个节点,然后在遍历中间节点的时候,就可以把右孩子指向当前节点,当前节点左孩子指向pre,即可
下面是代码
解答:下面我创建了一个头节点,其他都与用中序遍历大体相同
#include "stdafx.h"
template<class type> class BinaryTree{
private:
Node<type> * root;
public:
Node<type> *& GetRoot(){return root;}
BinaryTree():root(nullptr){}
BinaryTree(type data):root(new Node<type>(data)){}
void BuildTree(Node<type> *& p);
void ToDoubleLink(Node<type> *& pre,Node<type>* cur);
Node<type>*& GetLeftGrandSon();
void MidOrder(Node<type> *r ){
if(r!=nullptr){
MidOrder(r->leftChild);
cout<<r->data<< " ";
MidOrder(r->rightChild);
}}
};
template<class type> void BinaryTree<type>::ToDoubleLink(Node<type> *& pre,Node<type>* cur){
if(cur!=nullptr&&pre!=nullptr){
ToDoubleLink(pre,cur->leftChild);
pre->rightChild=cur;
cur->leftChild=pre;
pre=cur;
ToDoubleLink(pre,cur->rightChild);
}
}
template<class type> Node<type>*& BinaryTree<type>::GetLeftGrandSon(){
Node<type> * p=root;
while(p->leftChild!=nullptr){
p=p->leftChild;
}
return p;
}
template<class type> void BinaryTree<type>::BuildTree(Node<type> *& p){
char c;
cin>>c;
if(c==' ')
p=nullptr;
else {
p=new Node<type>(c);
BuildTree(p->leftChild);
BuildTree(p->rightChild);
}
return ;
}
int main(){
BinaryTree<char> link('D');
//link.BuildTree(link.GetRoot());//根据输入构造树
Node<char> * head=new Node<char>('0');
Node<char>* root=link.GetRoot();
root->SetLeftChild(new Node<char>('B'));
root->SetRightChild(new Node<char>('E'));
root->GetLeftChild()->SetLeftChild(new Node<char>('A'));
root->GetLeftChild()->SetRightChild(new Node<char>('C'));
root->GetRightChild()->SetLeftChild(new Node<char>('F'));
root->GetRightChild()->SetRightChild(new Node<char>('G'));
link.MidOrder(link.GetRoot());
link.ToDoubleLink(head,link.GetRoot());
Node<char>* p=link.GetLeftGrandSon();
while(p){
cout<<p->GetData()<<" ";
p=p->GetRightChild();
}
system("pause");
}