【典型习题整理】数据结构与算法作业

数据结构与算法


       刚学过“树”这种数据结构,现在呈上一种典型的树——二叉树的实现及相关操作。

代码如下:

package NineWeek;

import java.util.*;

public class Tree {

	public Tree left;
	public Tree right;
	public Object value;
	
	public Tree(Object value){this.value=value;}
	public Tree(){}
	
	//以下是基本方法
	/**
	 * 增加左子树
	 * 
	 * @param value
	 */
	public void addLeft(Object value){
		Tree leftChildren=new Tree(value);
		this.left=leftChildren;
	}
	/**
	 * 增加右子树
	 * 
	 * @param value
	 */
	public void addRight(Object value){
		Tree rightChildren=new Tree(value);
		this.right=rightChildren;
	}
	@Override  
	public boolean equals(Object obj){
		if(!(obj instanceof Tree)) return false;
		return this.value.equals(((Tree) obj).value);
	}
	@Override  
	public int hashCode(){
		return this.value.hashCode();
	}
	@Override  
	public String toString(){
		return this.value==null ? "" : String.valueOf(this.value);
	}
	
	//以下是功能方法(函数)
	
	/** 
     * getTreeNum: 判断树中节点个数 
     *  
     * @param root 根节点 
     *            
     * @return int 返回类型 
     */  
	public int getTreeNum(Tree root){
		return (root==null) ? 0 : getTreeNum(root.left)+getTreeNum(root.right)+1;
	}
	
	/**
	 * getTreeDepth:返回树的深度
	 * 
	 * @param root
	 * 
	 * @return 树的深度
	 */
	public int getTreeDepth(Tree root){
		return (root==null) ? 0 : Math.max(getTreeDepth(root.left)+1, getTreeDepth(root.right)+1);
	}
	
	/** 
     * visitNode: 访问node节点 
     *  
     * @param node void 返回类型 
     */  
	private void visitNode(Tree node){
		System.out.println(node.value+"\t");
	}
	
	/**
	 * preOrderTravel:前序遍历
	 * 
	 * @param root 根节点
	 */
	public void preOrderTravel(Tree root){
		if(root==null) return;
		visitNode(root);
		preOrderTravel(root.left);
		preOrderTravel(root.right);
	}
	
	/**
	 * 中序遍历
	 * 
	 * @param root 根节点
	 */
	public void midOrderTravel(Tree root){
		if(root==null) return;
		midOrderTravel(root.left);
		visitNode(root);
		midOrderTravel(root.right);
	}
	
	/** 
     * backOrderTravel: 后序遍历 
     *  
     * @param root 根节点
     */ 
	public void backOrderTravel(Tree root){
		if(root==null) return;
		backOrderTravel(root.left);  
        backOrderTravel(root.right);  
        visitNode(root);  
	}
	
	/**
	 * 分层遍历
	 * 
	 * @param root 根节点
	 */
	public void levelTravel(Tree root){
		Queue<Tree> q=new LinkedList<Tree>();
		q.offer(root);
		while(!q.isEmpty()){
			Tree temp=q.poll();
			visitNode(temp);
			if(temp.left!=null)
				q.offer(temp.left);
			if(temp.right!=null)
				q.offer(temp.right);
		}
	}
	
	/**
	 * 求第k层节点个数
	 * 
	 * @param root 根节点
	 * 
	 * @param k 层数(从0开始)
	 * 
	 * @return 节点个数
	 */
	public int getNumFromLevelK(Tree root, int k){
		if(root==null||k<0) return 0;
		if(k==0) return 1;
		return getNumFromLevelK(root.left, k-1)+getNumFromLevelK(root.right, k-1);
	}
	
	/** 
     * getLeafNum: 求二叉树中叶子节点的个数 
     *  
     * @param root 
     * @return int 返回类型 
     */  
	public int getLeafNum(Tree root){
		if(root==null) return 0;
		if(root.left==null&&root.right==null) return 1;
		return getLeafNum(root.left)+getLeafNum(root.right);
	}
	
	/**
	 * 交换某节点下的左右子树
	 * 
	 * @param root 目标节点
	 * 
	 * @return 树
	 */
	public Tree exchange(Tree root){
		if(root==null) return null;
		Tree le=root.left;
		root.left=root.right;
		root.right=le;
		return root;
	}
	
	/**
	 * 查看node是否是root的子节点 
	 * 
	 * @param root
	 * 
	 * @param node
	 * 
	 * @return
	 */
	public boolean nodeIsChild(Tree root, Tree node){
		if(root==null||node==null) return false;
		if(root==node) return true;
		return nodeIsChild(root.left, node)||nodeIsChild(root.right, node);
	}
	
	/**
	 * 返回两个节点lnode和rnode的最近根节点
	 * 
	 * @param root 根节点
	 * 
	 * @param lnode节点1
	 * 
	 * @param rnode节点2
	 * 
	 * @return 最近公共父节点 
	 */
	public Tree findAllFatherNode(Tree root, Tree lnode, Tree rnode){
		if(root==lnode||root==rnode) return root;
		if(root==null||lnode==null||rnode==null) return null;
		
		// 如果lNode是左子树的节点
		if(nodeIsChild(root.left, lnode)){
			if(nodeIsChild(root.right, rnode)) return root;
			else return findAllFatherNode(root.left, lnode, rnode);
		}
		else{
			if(nodeIsChild(root.left, rnode)) return root;
			else return findAllFatherNode(root.right, lnode, rnode);
		}
	}
	
	/**
	 * 根据前序和中序构建二叉树 
	 * 
	 * @param pre前序序列
	 * 
	 * @param mid中序序列
	 * 
	 * @return二叉树
	 */
	public Tree getTreeFromPre_Mid(List<Integer> pre, List<Integer> mid){
		if(pre==null||mid==null||pre.size()==0||mid.size()==0) return null;
		if(pre.size()==1) return new Tree(pre.get(0));
		// 找出根节点在中序中的位置  
		Tree root = new Tree(pre.get(0));
		int index=0;
		// 构建左子树的前序 
		while(!mid.get(index++).equals(pre.get(0))){}
		
		// 构建左子树的前序 
		List<Integer> preLeft=new ArrayList<Integer>(index);
		// 左子树的中序  
		List<Integer> midLeft=new ArrayList<Integer>(index);
		
		for(int i=0;i<index;i++) preLeft.add(pre.get(i));
		for(int i=0;i<index-1;i++) midLeft.add(mid.get(i));
		
		// 重建左子树  
		root.left=getTreeFromPre_Mid(preLeft, midLeft);
		// 右子树的前序  
		List<Integer> preRight=new ArrayList<Integer>(pre.size() - index - 1);
		// 右子树的中序  
		List<Integer> midRight=new ArrayList<Integer>(pre.size() - index - 1);
		
		for(int i=0;i<=pre.size()-index-1;i++) preRight.add(pre.get(index+1));
		for(int i=0;i<=pre.size()-index-1;i++) midRight.add(mid.get(index+1));
		// 重建→子树  
		root.right=getTreeFromPre_Mid(preRight, midRight);
		return root;
	}
	
	public boolean equals(Tree node1, Tree node2){
		if(node1==null&&node2==null) return true;
		else if(node1==null||node2==null) return false;
		
		boolean isEqual = node1.value.equals(node2.value);  
		boolean isLeftEqual = equals(node1.left, node2.left);
        boolean isRightEqual = equals(node1.right, node2.right);  
        return isEqual && isLeftEqual && isRightEqual;  
	}
}

测试代码及结果:

package NineWeek;

import java.util.*;

public class TreeTest {
	
	public static void main(String args){
		
		Tree t=new Tree(1);
		t.addLeft(2);
		t.addRight(3);
		t.left.addLeft(4);
		t.left.addRight(5);

		System.out.println("前序遍历:");
		t.preOrderTravel(t);
		System.out.println("\n中序遍历:");
		t.midOrderTravel(t);
		System.out.println("\n后序遍历:");
		t.backOrderTravel(t);
		System.out.println("\n层次遍历:");
		t.levelTravel(t);
		
		System.out.println();
		
		System.out.println("树的深度:");
		System.out.println(t.getTreeDepth(t));
		System.out.println("叶子个数:");
		System.out.println(t.getLeafNum(t));
		System.out.println("节点个数:");
		System.out.println(t.getTreeNum(t));
		System.out.println("第二层节点数:");
		System.out.println(t.getNumFromLevelK(t, 2));
		
		System.out.println();
		
		System.out.println("通过前序和中序构建树:");
		List<Integer> pre = new ArrayList<Integer>();
        pre.add(1);
        pre.add(2);
        pre.add(4);
        pre.add(5);
        pre.add(3);
        List<Integer> mid = new ArrayList<Integer>();
        mid.add(4);
        mid.add(2);
        mid.add(5);
        mid.add(1);
        mid.add(3);
		Tree root=t.getTreeFromPre_Mid(pre, mid);

		System.out.println("比较两树是否相等");
		System.out.println(t.equals(t, root));
	}
}

结果如下:

中序遍历测试:
4 2 5 1 3
前序遍历测试:
1 2 4 5 3
后序遍历测试:
4 5 2 3 1
层次遍历测试:
1 2 3 4 5
树的深度:3
树的叶子个数:3
树的节点个数:5
第2层节点个数为:2
通过前序和中序构建树测试:
1 2 3 4 5
构建的树比较测试:
true

【注】:部分空行可能显示有误,但不影响检查结果。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值