二叉树通过遍历可以用于转化成一个链表(插入构建链表)。但是如果没有而外的链表呢? 这就用到"线索化二叉树",也就是一个二叉树(可以是排序二叉树)在座遍历(例如中序)的时候,去更新每个节点的"前驱"和"后继"的节点关系,得到一个二叉链表。然后从最左节点开始,遍历所有的"后继"节点,就得到一个二叉链表的所有数据。分别用C++和Java来实现。
(2) 如果不允许修改2叉树本身,那么就要借助于线索化2叉树,这个会复杂一点,但是能够做到同样的效果。
(1)第一种情况,也是简单的情况,允许以侵入的方式把二叉树变成双向链表。这需要做几件事情。对于任意一个节点来说,如果左子树存在,那么左子树变成2叉链表以后,左子树的"最后的指针"指向当前节点。如果右子树存在,那么当前节点的新的右节点(也就是2叉链表的next),就是右节点的最左元素。函数返回右子树的"最后指针"。Java程序如下:
- public class my{
- public static void main(String[] args){
- class node{
- node left=null;
- node right=null;
- int data=0;
- node(int d){data=d;}
- void appendLeft(node n){
- if(left==null)left=n;
- else left.append(n);
- }
- void appendRight(node n){
- if(right==null)right=n;
- else right.append(n);
- }
- void append(node n){
- if(data>n.data)appendLeft(n);
- else appendRight(n);
- }
- void print(){
- if(left!=null)left.print();
- System.out.print(","+data);
- if(right!=null)right.print();
- }
- node helper(){//返回最后的节点
- if(left!=null){
- node leftPtr=left.helper();
- leftPtr.right=this;
- }
- node ret=this;
- if(right!=null){
- ret=right.helper();
- node rightPtr=right.LeftestNode();
- right=rightPtr;
- }
- return ret;//叶子节点总是返回自身
- }
- node LeftestNode(){//叶子节点总是返回自身
- node p=this;
- while(p.left!=null){
- p=p.left;
- }
- return p;
- }
- }
- class tree{
- node root=null;
- tree(int d){root=new node(d);}
- void append(int d){root.append(new node(d));}
- void display(){root.print();}
- void Tree2List(){
- node leftest=root.LeftestNode();
- root.helper();
- while(leftest!=null){
- System.out.print(","+leftest.data);
- leftest=leftest.right;
- }
- }
- }
- tree t=new tree(5);
- t.append(2);
- t.append(7);
- t.append(1);
- t.append(6);
- t.append(8);
- t.append(3);
- t.display();
- System.out.println("\n===========");
- t.Tree2List();
- }
- }
public class my{
public static void main(String[] args){
class node{
node left=null;
node right=null;
int data=0;
node(int d){data=d;}
void appendLeft(node n){
if(left==null)left=n;
else left.append(n);
}
void appendRight(node n){
if(right==null)right=n;
else right.append(n);
}
void append(node n){
if(data>n.data)appendLeft(n);
else appendRight(n);
}
void print(){
if(left!=null)left.print();
System.out.print(","+data);
if(right!=null)right.print();
}
node helper(){//返回最后的节点
if(left!=null){
node leftPtr=left.helper();
leftPtr.right=this;
}
node ret=this;
if(right!=null){
ret=right.helper();
node rightPtr=right.LeftestNode();
right=rightPtr;
}
return ret;//叶子节点总是返回自身
}
node LeftestNode(){//叶子节点总是返回自身
node p=this;
while(p.left!=null){
p=p.left;
}
return p;
}
}
class tree{
node root=null;
tree(int d){root=new node(d);}
void append(int d){root.append(new node(d));}
void display(){root.print();}
void Tree2List(){
node leftest=root.LeftestNode();
root.helper();
while(leftest!=null){
System.out.print(","+leftest.data);
leftest=leftest.right;
}
}
}
tree t=new tree(5);
t.append(2);
t.append(7);
t.append(1);
t.append(6);
t.append(8);
t.append(3);
t.display();
System.out.println("\n===========");
t.Tree2List();
}
}
(2) 如果不允许修改2叉树本身,那么就要借助于线索化2叉树,这个会复杂一点,但是能够做到同样的效果。
分别用C++和Java实现
- #include<functional>
- using namespace std;
- template<class Comp>
- class node{
- size_t data;
- node* pLeft;
- node* pRight;
- bool lTag;//true表示node*pLeft/pRight是线索,false表示指针
- bool rTag;
- public:
- node( size_t d ):
- data(d),
- pLeft(nullptr),
- pRight(nullptr),
- lTag(true),
- rTag(true)
- {}
- void append( node* p ){
- if( Comp()( p->data, data ) ){
- appendLeft( p );
- }else{
- appendRight( p );
- }
- }
- void appendLeft( node* p ){
- if( pLeft == nullptr ){
- pLeft = p;
- }else{
- pLeft->append( p );
- }
- lTag=false;
- }
- void appendRight( node* p ){
- if( pRight == nullptr ){
- pRight = p;
- }else{
- pRight->append( p );
- }
- rTag=false;
- }
- ~node(){
- if(pLeft && (lTag==false))delete pLeft;
- if(pRight&& (rTag==false))delete pRight;
- }
- void printTree(){//中序遍历打印
- if(pLeft)pLeft->printTree();
- printf("%d,",data);
- if(pRight)pRight->printTree();
- }
- void ToThreadedBinarytree(){//中序线索2叉树
- static node* pre=nullptr;
- if(pLeft){
- pLeft->ToThreadedBinarytree();
- }else{
- pLeft=pre;
- lTag=true;
- }
- if(pre){
- if(pre->pRight==nullptr){
- pre->pRight=this;
- pre->rTag=true;
- }
- }
- pre=this;
- if(pRight){
- pRight->ToThreadedBinarytree();
- }
- }
- void printList(){
- node*p=this;
- while(p->pLeft && (p->lTag==false)){
- p=p->pLeft;
- }//找到当前树的最左节点
- p->printThreaded();
- }
- void printThreaded(){//寻找后继结点并打印
- printf("%d,",data);
- if(rTag){
- if(pRight)pRight->printThreaded();
- }else{
- if(pRight)pRight->printList();
- }
- }
- };
- template<class T>
- struct sortedTree{
- node<T>* pRoot;
- sortedTree():pRoot(nullptr){}
- ~sortedTree(){if(pRoot)delete pRoot;}
- void append( size_t n ){
- node<T>* p=new node<T>(n);
- if( pRoot == nullptr ){
- pRoot = p;
- }else{
- pRoot->append( p );
- }
- }
- void printTree(){
- if(pRoot)pRoot->printTree();
- }
- void convertList(){
- if(pRoot){
- pRoot->ToThreadedBinarytree();
- printf("\n");
- pRoot->printList();
- }
- }
- };
- int main(int argc, char* const argv[]){
- sortedTree< less<size_t> > tree;
- tree.append( 3 );
- tree.append( 7 );
- tree.append( 4 );
- tree.append( 2 );
- tree.append( 5 );
- tree.append( 1 );
- tree.append( 6 );
- tree.printTree();
- printf("\n");
- tree.convertList();//打印线索化的二叉树
- printf("\n");
- return 0;
- }
#include<functional>
using namespace std;
template<class Comp>
class node{
size_t data;
node* pLeft;
node* pRight;
bool lTag;//true表示node*pLeft/pRight是线索,false表示指针
bool rTag;
public:
node( size_t d ):
data(d),
pLeft(nullptr),
pRight(nullptr),
lTag(true),
rTag(true)
{}
void append( node* p ){
if( Comp()( p->data, data ) ){
appendLeft( p );
}else{
appendRight( p );
}
}
void appendLeft( node* p ){
if( pLeft == nullptr ){
pLeft = p;
}else{
pLeft->append( p );
}
lTag=false;
}
void appendRight( node* p ){
if( pRight == nullptr ){
pRight = p;
}else{
pRight->append( p );
}
rTag=false;
}
~node(){
if(pLeft && (lTag==false))delete pLeft;
if(pRight&& (rTag==false))delete pRight;
}
void printTree(){//中序遍历打印
if(pLeft)pLeft->printTree();
printf("%d,",data);
if(pRight)pRight->printTree();
}
void ToThreadedBinarytree(){//中序线索2叉树
static node* pre=nullptr;
if(pLeft){
pLeft->ToThreadedBinarytree();
}else{
pLeft=pre;
lTag=true;
}
if(pre){
if(pre->pRight==nullptr){
pre->pRight=this;
pre->rTag=true;
}
}
pre=this;
if(pRight){
pRight->ToThreadedBinarytree();
}
}
void printList(){
node*p=this;
while(p->pLeft && (p->lTag==false)){
p=p->pLeft;
}//找到当前树的最左节点
p->printThreaded();
}
void printThreaded(){//寻找后继结点并打印
printf("%d,",data);
if(rTag){
if(pRight)pRight->printThreaded();
}else{
if(pRight)pRight->printList();
}
}
};
template<class T>
struct sortedTree{
node<T>* pRoot;
sortedTree():pRoot(nullptr){}
~sortedTree(){if(pRoot)delete pRoot;}
void append( size_t n ){
node<T>* p=new node<T>(n);
if( pRoot == nullptr ){
pRoot = p;
}else{
pRoot->append( p );
}
}
void printTree(){
if(pRoot)pRoot->printTree();
}
void convertList(){
if(pRoot){
pRoot->ToThreadedBinarytree();
printf("\n");
pRoot->printList();
}
}
};
int main(int argc, char* const argv[]){
sortedTree< less<size_t> > tree;
tree.append( 3 );
tree.append( 7 );
tree.append( 4 );
tree.append( 2 );
tree.append( 5 );
tree.append( 1 );
tree.append( 6 );
tree.printTree();
printf("\n");
tree.convertList();//打印线索化的二叉树
printf("\n");
return 0;
}
- public class TreeToList{
- static class node{
- node pLeft;
- node pRight;
- boolean lTag;//true代表是线索
- boolean rTag;
- int data;
- node(int d){
- data=d;
- pLeft=null;
- pRight=null;
- lTag=false;
- rTag=false;
- }
- void append(node n){
- if(data>n.data){
- appendLeft(n);
- }
- else{
- appendRight(n);
- }
- }
- void appendLeft(node n){
- if(pLeft==null){
- pLeft=n;
- }
- else{
- pLeft.append(n);
- }
- lTag=false;
- }
- void appendRight(node n){
- if(pRight==null){
- pRight=n;
- }
- else{
- pRight.append(n);
- }
- rTag=false;
- }
- void printNode(){
- if(pLeft !=null){
- pLeft.printNode();
- }
- System.out.println(","+data);
- if(pRight!=null){
- pRight.printNode();
- }
- }
- static node pre;
- static{
- pre=null;
- }
- void ToThreadedBinaryTree(){
- if(pLeft!=null){
- pLeft.ToThreadedBinaryTree();
- }else{
- pLeft=pre;
- lTag=true;
- }
- if(pre!=null){
- if(pre.pRight==null){
- pre.pRight=this;
- pre.rTag=true;
- }
- }
- pre=this;
- if(pRight!=null){
- pRight.ToThreadedBinaryTree();
- }
- }
- void printList(){
- node p=this;
- while(p.pLeft!=null && p.lTag==false){
- p=p.pLeft;
- }//找到当前树的最左节点
- p.printThreaded();
- }
- void printThreaded(){
- System.out.println(","+data);
- if(rTag){
- if(pRight!=null){
- pRight.printThreaded();
- }
- }else{
- if(pRight!=null){
- pRight.printList();
- }
- }
- }
- }//end class node
- static class BTree{
- node pRoot;
- void append(node n){
- if(pRoot==null){
- pRoot=n;
- }
- else{
- pRoot.append(n);
- }
- }
- void printTree(){
- if(pRoot!=null){
- pRoot.printNode();
- }
- }
- void convertList(){
- if(pRoot!=null){
- pRoot.ToThreadedBinaryTree();
- pRoot.printList();
- }
- }
- }//end class BTree
- public static void main(String[] args) {
- BTree t=new BTree();
- t.append(new node(3));
- t.append(new node(7));
- t.append(new node(4));
- t.append(new node(2));
- t.append(new node(5));
- t.append(new node(1));
- t.append(new node(6));
- t.printTree();
- System.out.println("========");
- t.convertList();
- }
- }
public class TreeToList{
static class node{
node pLeft;
node pRight;
boolean lTag;//true代表是线索
boolean rTag;
int data;
node(int d){
data=d;
pLeft=null;
pRight=null;
lTag=false;
rTag=false;
}
void append(node n){
if(data>n.data){
appendLeft(n);
}
else{
appendRight(n);
}
}
void appendLeft(node n){
if(pLeft==null){
pLeft=n;
}
else{
pLeft.append(n);
}
lTag=false;
}
void appendRight(node n){
if(pRight==null){
pRight=n;
}
else{
pRight.append(n);
}
rTag=false;
}
void printNode(){
if(pLeft !=null){
pLeft.printNode();
}
System.out.println(","+data);
if(pRight!=null){
pRight.printNode();
}
}
static node pre;
static{
pre=null;
}
void ToThreadedBinaryTree(){
if(pLeft!=null){
pLeft.ToThreadedBinaryTree();
}else{
pLeft=pre;
lTag=true;
}
if(pre!=null){
if(pre.pRight==null){
pre.pRight=this;
pre.rTag=true;
}
}
pre=this;
if(pRight!=null){
pRight.ToThreadedBinaryTree();
}
}
void printList(){
node p=this;
while(p.pLeft!=null && p.lTag==false){
p=p.pLeft;
}//找到当前树的最左节点
p.printThreaded();
}
void printThreaded(){
System.out.println(","+data);
if(rTag){
if(pRight!=null){
pRight.printThreaded();
}
}else{
if(pRight!=null){
pRight.printList();
}
}
}
}//end class node
static class BTree{
node pRoot;
void append(node n){
if(pRoot==null){
pRoot=n;
}
else{
pRoot.append(n);
}
}
void printTree(){
if(pRoot!=null){
pRoot.printNode();
}
}
void convertList(){
if(pRoot!=null){
pRoot.ToThreadedBinaryTree();
pRoot.printList();
}
}
}//end class BTree
public static void main(String[] args) {
BTree t=new BTree();
t.append(new node(3));
t.append(new node(7));
t.append(new node(4));
t.append(new node(2));
t.append(new node(5));
t.append(new node(1));
t.append(new node(6));
t.printTree();
System.out.println("========");
t.convertList();
}
}