二叉树以及线索二叉树

二叉树

		(一)一颗非空二叉树的第i层最多有2的(i-1)次方个结点。
		(二)一颗深度为k的二叉树中,最多有2的(k-1)次方个结点
		(三)对于一个非空的二叉树,若叶子结点数为A,度数为2的结点个数为B。则A=B+1
//二叉树的先序递归遍历
 public void PreOrder(BiTree root){
        if (root!=null){
            Visit(root);//访问结点
            PreOrder(root.left);//递归遍历左孩子
            PreOrder(root.right);//递归遍历右孩子
        }
    }
 //中序遍历或者后序遍历就是把Visit方法放在中间或者后面
 //二叉树的非递归遍历
 public void NRPreOrder(BiTree root){
        //利用栈来实现遍历
        BiTree stack[]=new BiTree[100];//建立一个100大小的栈
        BiTree p;
        int top=-1;//栈顶指针初始化
        if (root==null) return;
        p=root;
        while (!(p==null&&top==-1)){
            //当p不为空或者top不为-1时执行外层循环
            while (p!=null){
                //如果p不为空
                Visit(p);//访问p结点的值
                top++;//栈顶指针+1
                stack[top]=p;//把p结点压入栈
                p=p.left;//p指向p的左孩子
            }
            if (top<0)break;//如果执行了上部循环top仍然为空,说明p为空,跳出循环
            else {
                //返回一层,读出栈顶元素,然后让p指向栈顶元素的右孩子
                p=stack[top];
                top--;
                p=p.right;
            }
        }

    }
 //二叉树的层次遍历
  public void LevelOrder(BiTree root){
        BiTree queue[]=new BiTree[100];//定义一个队列
        int front,rear;//定义头指针和尾指针
        if(root==null)return;
        front=-1;
        rear=0;
        queue[rear]=root;
        while (front!=rear){
            front++;
            Visit(queue[front]);
            if (queue[front].left!=null){
                rear++;
                queue[rear]=queue[front].left;
            }
            if (queue[front].left!=null){
                rear++;
                queue[rear]=queue[front].left;
            }
        }


    }
 //简易的Visit方法
 public void Visit(BiTree root){
        System.out.println(root.value);
 }
 //定义的BiTree类
 class BiTree{
    int value;
    BiTree left;
    BiTree right;
}
    
    
二、线索二叉树
		线索二叉树就是利用结点的空的左孩子来存储结点的直接前驱结点,当结点的右孩子为空时,
利用右孩子来存储结点的后继结点。
		改变原来二叉链表的结构,为每个结点增设两个标志位域ltag和rtag,当ltag=0时,left指向左孩子,当ltag=1时,left指向结点的前驱结点,rtag同理
//中序线索二叉树的建立
	BiThrTree pre;//pre指向当前遍历结点的前驱结点
    public BiThrTree InOrderThr(BiThrTree root) {//中序遍历root,并将其中序线索化
            BiThrTree head=new BiThrTree();//建立头结点
            head.ltag=0;
            head.rtag=1;
            head.right=head;//右指针回指
            if(root==null) head.left=head;//若二叉树为空,则左指针回指
            else {
                head.left=root;
                pre=head;
                InTreading(root);//中序线索化
                pre.right=head;//最后一个结点线索化
                pre.rtag=1;
                head.right=pre;
            }
        return head;

    }
    public void InTreading(BiThrTree p){
        if(p!=null){
            InTreading(p.left);//左子树线索化
            if(p.left==null){//前驱线索
                p.ltag=1;
                p.left=pre;
            }
            if (pre.right==null){//后继线索
                pre.rtag=1;
                pre.right=p;
            }
            pre=p;
            InTreading(p.right);//右子树线索化
        }

    }

中序线索二叉树的遍历:
一:寻找结点的前驱结点
1.如果该结点的左标志为1,那么其左指针域做指向的结点便是它的前驱结点
2.如果该结点的左标志位0,那么说明该结点有左孩子,根据中序遍历的定义,它的前驱结点是以该节点的左孩子为
根节点的子树的最右结点。故需要沿着其左子树的右指针链向下查找,当某结点的右标志为1时,它就是所要找的前驱
结点。

	public BiThrTree InPreNode(BiThrTree p){
        BiThrTree pre;
        pre=p.left;//令pre指向p的左孩子,如果左孩子是指向其前驱结点,就返回,如果有左孩子,则寻找以左孩子为				根节点的最右结点
        if(p.ltag!=1){
            while (pre.rtag==0) pre=pre.right;
        }
        return pre;
    }

二:寻找结点的后继结点

	1.如果该结点的右标志为1,那么其右指针域做指向的结点便是它的后继结点
	2.如果该结点的右标志位0,那么说明该结点有右孩子,根据中序遍历的定义,它的后继结点是以该节点的右孩子为
	根节点的子树的最左结点。故需要沿着其右子树的左指针链向下查找,当某结点的左标志为1时,它就是所要找的后继
	结点。
	public BiThrTree InPostNode(BiThrTree p){
        BiThrTree post;
        post=p.right;//令pre指向p的左孩子,如果左孩子是指向其前驱结点,就返回,如果有左孩子,则寻找以左孩子为根节点的最右结点
        if(p.rtag!=1){
            while (post.ltag==0) post=post.left;
        }
        return post;
    }

三:线索树的遍历

以中序为例,利用在中序线索二叉树上寻找后继结点和前驱结点的算法,就可以遍历二叉树的所有结点,即先找到某许汴利的第一个结点,然后再一次查询其后继,或者先找到最后一个结点,然后再依次查询其前驱。
	public BiThrTree Search(BiThrTree head){
        BiThrTree p;
        p=head.left;
        while (p.ltag==0&&p!=head) p=p.left;//寻找中序遍历的第一个结点
        while (p!=head){
            p=InPostNode(p);//寻找它的后继结点
            Visit(p);
        }
    }
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值