今日分数据结构作业:二叉树简单操作

版权声明: https://blog.csdn.net/King8611/article/details/82939122

又是一次非常有趣(sangxinbingkuang)的作业。

这么简单的作业居然写了一下午,我也是醉了。

看来下次要调整好状态再写作业了QAQ。

先看实验要求:

后三道题懒得写了,就不发要求了/滑稽。

代码(附带详细注释):

import java.util.*;
public class Main {
	/*
	 * 这次作业有点多,居然写了一下午
	 * 中间收了条信息,突然情绪不好了
	 * 其实认真写的话1h完全OK的
	 */
	public static void main(String[] args) {
		BinaryTree<Integer> tree=new BinaryTree<Integer>();
		tree.head=new Node<Integer>();
		tree.head.data=new Integer(1);
		tree.head.left=new Node<Integer>(new Integer(2));
		tree.head.right=new Node<Integer>(new Integer(3));
		tree.head.left.left=new Node<Integer>(new Integer(4));
		tree.head.left.right=new Node<Integer>(new Integer(5));
		tree.head.right.left=new Node<Integer>(new Integer(6));
		tree.head.right.right=new Node<Integer>(new Integer(7));
		/*
		 * 					1
		 * 	   	    2                3
		 *    	4      5        6         7  
		 * 构建的树大概就是这样子。
		 * 下面遍历这棵树
		 */
		System.out.println("中跟递归结果:");
		tree.ldr();
		System.out.println("后根递归结果:");
		tree.lrd();
		System.out.println("后根非递归结果:");
		tree.lrd2();
		System.out.println("所有节点平均数是:"+ave(tree));
		tree.swap();//反转树
		System.out.println("反转树后中根遍历的结果:");
		tree.ldr();//中序遍历
	}
	
	//=======计算平均数的方法
	/*
	 * 因为JAVA不存在指针,引用就是指针,我看Integer中没有add或者set方法,就自己写了个简单的Integer类
	 * 然后简单的递归求平均数
	 * calculate函数求树sum和点个数,然后再ave函数里算出。
	 */
	static int ave(BinaryTree<Integer> tree) {
		Integer sum=new Integer(0),n=new Integer(0);
		calculate(tree.head,sum,n);
		return sum.v/n.v;
	}
	static void calculate(Node<Integer> node,Integer sum,Integer n) {
		if(node!=null) {
			n.add(1);
			sum.add(node.data);
			calculate(node.left,sum,n);
			calculate(node.right,sum,n);
		}
	}
}
class BinaryTree<T>{
	Node<T> head;
	public void swap() {
		swap(head);
	}
	/*
	 * swap函数,很简单一个递归就完成了。
	 */
	public void swap(Node<T> node) {
		if(node!=null) {
			Node<T> l=node.left;
			Node<T> r=node.right;
			node.left=r;
			node.right=l;
			swap(node.left);
			swap(node.right);
		}
	}
	//====中根遍历递归==============================================
	public void ldr() {
		ldr(head);
		System.out.println();
	}
	private void ldr(Node<T> node) {
		if(node!=null) {
			ldr(node.left);
			System.out.print(node.data+" ");
			ldr(node.right);
		}
	}
	//====后根遍历递归==============================================
	 public void lrd() {
		 lrd(head);
		 System.out.println();
	 }
	private void lrd(Node<T> node) {
		if(node!=null) {
			lrd(node.left);
			lrd(node.right);
			System.out.print(node.data+" ");
		}
	}
	//====后根非递归===============================================
	/*
	 * 递归遍历那么简单易懂好写
	 * 而且时间复杂度上两者基本一样
	 * 空间复杂度,递归更是优于非递归
	 * 真是不明白为啥要用非递归
	 * 真是丧心病狂
	 */
	public void lrd2() {
		if(head==null) 
			return;
		Stack<Node<T>> stack=new Stack<Node<T>>();
		stack.push(head);
		Node<T> last=head;
		Node<T> p=head;
		/*
		 * 看了半天,好像还有不同的方法,
		 * 我用了个简单的,写了3min,debug15min。气人。QAQ
		 * 其实原理也很简单。
		 * 就是先把头入栈
		 * 然后入栈右,入栈左。
		 * 如果左右都是null,打印这个值
		 * 同时用一个last记录现在打印的点。
		 * 如果(p.right==null&&last==p.left)||last==p.right
		 * 说明这个点的双子都被打印过了,然后打印这个点。
		 * 入栈的时候要先右后左。因为取出来的方法是反过来的。
		 */
		while(!stack.isEmpty()){
			p=stack.peek();
			if((p.left==null&&p.right==null)||(p.right==null&&last==p.left)||last==p.right) {
				System.out.print(p.data+" ");
				stack.pop();
				last=p;
			}else {
				if(p.right!=null) {
					stack.push(p.right);
				}
				if(p.left!=null) {
					stack.push(p.left);
				}
			}
		}
		System.out.println();
	}
}
class Node<T>{
	Node<T> left;
	Node<T> right;
	T data;
	public Node(){
		
	}
	public Node(T v){
		data=v;
	}
}
/*
 * 我是一个手写的integer
 */
class Integer{
	int v;
	public Integer(int v) {
		this.v=v;
	}
	public void add(int x) {
		this.v+=x;
	}
	public void add(Integer x) {
		this.v+=x.v;
	}
	public String toString() {
		return v+"";
	}
}

猜你喜欢

转载自blog.csdn.net/King8611/article/details/82939122