把二叉树转成双向链表
public class TestBinTree {
private static int[] array={2,3,6,1,4,8,9,5};private static List<Node> nodeList=null;
public static void main(String args[]){
BinTree bintree=new BinTree();
bintree.showBinTree(array, 0);
nodeList=bintree.createBinTree(array, nodeList);
System.out.println("先序遍历:");
bintree.first_Traversal(nodeList.get(0));
System.out.println("\n中序遍历:");
bintree.order_Traversal(nodeList.get(0));
System.out.println("\n后序遍历:");
bintree.after_Traversal(nodeList.get(0));
Node newNode= bintree.doubleLink(nodeList.get(0));
System.out.println("\n转为二叉链表后:");
bintree.showDoubleLink(newNode, true);
}
}
class BinTree{
public List<Node> createBinTree(int[] array,List<Node> nodeList){//根据数组创建链表
nodeList=new LinkedList<Node>();
for(int nodeIndex=0;nodeIndex<array.length;nodeIndex++){
nodeList.add(new Node(array[nodeIndex]));
}
for(int parentIndex=0;parentIndex<array.length/2;parentIndex++){
if(parentIndex!=array.length/2-1){
nodeList.get(parentIndex).left=nodeList.get(parentIndex*2+1);
nodeList.get(parentIndex).right=nodeList.get(parentIndex*2+2);
}else{
nodeList.get(parentIndex).left=nodeList.get(parentIndex*2+1);
if(array.length%2==1){
nodeList.get(parentIndex).right=nodeList.get(parentIndex*2+2);
}
}
}
return nodeList;
}
public Node doubleLink(Node node){//二叉链表转双向链表
if(node==null)
return null;
Node left=doubleLink(node.left);//把左子树转成二叉链表
Node right=doubleLink(node.right);//把右子树转成二叉链表
node.left=null; //释放该节点的左右两子树
node.right=null;
if(left!=null){//如果左边不为空的话
left=LinkNode(left,1);//找到左子节点(已转为二叉链表)的最后端,保存到left中
node.left=left;//当前的节点的左边指向返回的节点
left.right=node;//返回的节点的右边指向该节点
}
if(right!=null){//这是右边的情况 同上 应该找到右子树(已转成二叉链表)的最左端来链接
right=LinkNode(right,0);
node.right=right;
right.left=node;
}
return node;//转成双向链表后返回节点
}
public Node LinkNode(Node node,int num){//表示要找到该双向链表需要链接的节点,或是最右端或是最左端
if(num==0){//0表示要找到该链表的最左端
if(node.left==null)
return node;
return LinkNode(node.left,num);
}else{//表示要找到该链表的最右端
if(node.right==null)
return node;
return LinkNode(node.right,num);
}
}
public void showDoubleLink(Node node,boolean flag){//输出打印双向链表,flag控制方向,先找到最左的节点
if(node.left!=null&&flag){//当左节点不为空并且flag为true;时一直往左迭代。直到找到最左点时
showDoubleLink(node.left,flag);
}else{//找到最左点了
flag=false;//把 flag设为false,避免在回调的时候,又跌回来了
if(node.right!=null){//当右子节点不为空时
System.out.print(node.data+"=");
showDoubleLink(node.right,flag);
}else{//当右子节点为空时,只输出当前节点的值,不再迭代下去了
System.out.print(node.data+" ");
}
}
}
public void first_Traversal(Node node){//先序遍历
if(node!=null){
System.out.print(node.data+" ");
first_Traversal(node.left);
first_Traversal(node.right);
}
}
public void order_Traversal(Node node){//中序遍历
if(node!=null){
order_Traversal(node.left);
System.out.print(node.data+" ");
order_Traversal(node.right);
}
}
public void after_Traversal(Node node){//后序遍历
if(node!=null){
after_Traversal(node.left);
after_Traversal(node.right);
System.out.print(node.data+" ");
}
}
public void showBinTree(int[] array,int index){//显示二叉树
if(array.length>Math.pow(2,index)-1){
showBinTree(array,index+1);
}else{
int totle=(int)Math.pow(2,index);//每行要打行的数
int linetotle=totle/2;//要打印的节点位置
int item=0; //要打印的数组的位置
for(int i=0;i<index;i++){//index表示有多少行
boolean flag=false;//控制节点输出
for(int j=0;j<totle;j++){
if(item<array.length){
if(j%linetotle!=0){//决定是输出节点还是空格
System.out.print(" ");
}else{
if(flag==false){
System.out.print(" ");
flag=true;
}else{
System.out.print(array[item]>9?array[item]:" "+array[item]);
item++;
flag=false;
}
}
}else{
System.out.print(" ");
}
}
linetotle=linetotle/2;
System.out.println();
}
}
}
class Node{//表示节点数据结构的类
Node left;
Node right;
int data;
Node(int newData){
left=null;
right=null;
data=newData;
}
}
}
最后的效果: