版权声明: 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+"";
}
}