Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -1,5 +1,10 @@
package me.lzb.basic.tree;

import java.util.ArrayList;
import java.util.LinkedList;
import java.util.List;
import java.util.Queue;

/**
* @author LZB
*/
Expand Down Expand Up @@ -180,30 +185,156 @@ private BinaryTreeNode<T> getFatherNode(BinaryTreeNode<T> node, T t) {
if (node.getRight() != null && node.getRight().getData().equals(t)) {
return node;
}
if (t.compareTo(node.getData()) > 0) {
if (node.isSmallerThanParam(t)) {
return getFatherNode(node.getRight(), t);
} else {
return getFatherNode(node.getLeft(), t);
}
}

private BinaryTreeNode<T> getNode(BinaryTreeNode<T> node, T t) {

/**
* 按层次遍历: levelVisit
*
* @return
*/
public List<T> levelVisit() {
List<T> result = new ArrayList<>();
levelVisit(result, root);
return result;
}


private void levelVisit(List<T> list, BinaryTreeNode<T> node) {
if (node == null) {
return node;
return;
}
//先放入根节点
Queue<BinaryTreeNode<T>> queue = new LinkedList<>();
queue.add(node);
while (!queue.isEmpty()) {
//上一层的节点个数
int l = queue.size();
//循环取出上一层这些节点
for (int i = 0; i < l; i++) {
BinaryTreeNode<T> temp = queue.poll();
list.add(temp.getData());
//把下一层的节点放入队列
if (temp.getLeft() != null) {
queue.add(temp.getLeft());
}
if (temp.getRight() != null) {
queue.add(temp.getRight());
}
}
}
}


if (node.getData().equals(t)) {
return node;
/**
* 判断一个二叉树是不是二叉查找树
*
* @return
*/
public boolean isValid() {
return isValid(true, root);
}

private boolean isValid(boolean b, BinaryTreeNode<T> node) {
if (!b || node == null) {
return b;
}

if (node.getLeft() == null && node.getRight() == null) {
return b;
}

if (node.getLeft() != null) {
if (node.isSmallerThanParam(node.getLeft())) {
b = false;
}
}

if (t.compareTo(node.getData()) > 0) {
return getNode(node.getRight(), t);
if (node.getRight() != null) {
if (node.isBiggerThanParam(node.getRight())) {
b = false;
}
}

boolean bl = isValid(b, node.getLeft());
boolean br = isValid(b, node.getRight());

return bl && br;
}


/**
* 获取两个节点的最小公共祖先
*
* @param n1
* @param n2
* @return
*/
public T getLowestCommonAncestor(T n1, T n2) {
return getLowestCommonAncestor(root, n1, n2);
}


private T getLowestCommonAncestor(BinaryTreeNode<T> node, T n1, T n2) {
if (node == null) {
return null;
}

//找到一个位于两者之间的节点,就是公共祖先。
if ((node.isSmallerThanParam(n1) && node.isBiggerThanParam(n2)) || (node.isSmallerThanParam(n2) && node.isBiggerThanParam(n1))) {
return node.getData();
}

//当前节点比n1和n2都小,最小公共祖先在右子树。
if (node.isSmallerThanParam(n1) && node.isSmallerThanParam(n2)) {
return getLowestCommonAncestor(node.getRight(), n1, n2);
}

//当前节点比n1和n2都大,最小公共祖先在左子树。
if (node.isBiggerThanParam(n1) && node.isBiggerThanParam(n2)) {
return getLowestCommonAncestor(node.getLeft(), n1, n2);
}
return null;
}


/**
* 给定两个值, 获得处于这两个值中间的节点
*
* @param n1
* @param n2
* @return
*/
public List<T> getNodesBetween(T n1, T n2) {
List<T> result = new ArrayList<>();
T s, b;
if (n1.compareTo(n2) < 0) {
s = n1;
b = n2;
} else {
return getNode(node.getLeft(), t);
s = n2;
b = n1;
}
getNodesBetween(result, root, s, b);

return result;
}

private void getNodesBetween(List<T> list, BinaryTreeNode<T> node, T small, T bigger) {
if (node == null) {
return;
}

if (node.isBiggerThanParam(small) && node.isSmallerThanParam(bigger)) {
list.add(node.getData());
}

getNodesBetween(list, node.getLeft(), small, bigger);
getNodesBetween(list, node.getRight(), small, bigger);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,7 @@ public void setRight(BinaryTreeNode<T> right) {
*/
public void insert(T d) {
BinaryTreeNode<T> b = new BinaryTreeNode(d);
if (isSmaller(d)) {
if (isBiggerThanParam(d)) {
//比父节点小,左边
if (this.left == null) {
this.left = b;
Expand All @@ -70,10 +70,22 @@ public void insert(T d) {
* @param d data
* @return true false
*/
private boolean isSmaller(T d) {
public boolean isBiggerThanParam(T d) {
return this.data.compareTo(d) > 0;
}

public boolean isBiggerThanParam(BinaryTreeNode<T> node) {
return isBiggerThanParam(node.getData());
}

public boolean isSmallerThanParam(T d) {
return this.data.compareTo(d) < 0;
}

public boolean isSmallerThanParam(BinaryTreeNode<T> node) {
return isSmallerThanParam(node.getData());
}

@Override
public String toString() {
// return getLeft() != null ? getLeft().getData().toString() : "" + ":" + getData().toString() + ":" + getRight() != null ? getRight().getData().toString() : "";
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -63,4 +63,37 @@ public void testRemoveMiddleNode() {
Assert.assertEquals(3, root.getLeft().getData().intValue());
Assert.assertEquals(4, root.getLeft().getRight().getData().intValue());
}

@Test
public void testLevelVisit() {
Assert.assertEquals("[6, 2, 8, 1, 4, 3]", tree.levelVisit().toString());
}

@Test
public void testIsValid() {
Assert.assertTrue(tree.isValid());
tree.getRoot().getRight().setData(5);
Assert.assertFalse(tree.isValid());
tree.getRoot().getRight().setData(8);
tree.getRoot().getLeft().getLeft().setData(5);
Assert.assertFalse(tree.isValid());
}

@Test
public void testGetLowestCommonAncestor() {
Assert.assertEquals(2l, tree.getLowestCommonAncestor(1, 4).longValue());
Assert.assertEquals(6l, tree.getLowestCommonAncestor(1, 8).longValue());
}


@Test
public void testGetNodesBetween() {
Assert.assertEquals("[6, 2, 4, 3]", tree.getNodesBetween(1, 8).toString());

Assert.assertEquals("[6]", tree.getNodesBetween(7, 4).toString());

Assert.assertEquals("[6, 2, 1, 4, 3, 8]", tree.getNodesBetween(20, 0).toString());
}


}
Original file line number Diff line number Diff line change
Expand Up @@ -135,6 +135,7 @@ public void addMethod(Method m) {
this.methods.add(m);
}

//函数的 方法名+参数类型+返回值,构成函数的唯一标识
public Method getMethod(String methodName, String paramAndReturnType) {
for (Method m : methods) {
int nameIndex = m.getNameIndex();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
import me.lzb.jvm.method.Method;

/**
* 定义了返回结果,有时候执行结束了是返回,或者,执行下一个方法,等等
* @author LZB
*/
public class ExecutionResult {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,24 +12,34 @@
*/
public class ExecutorEngine {

//虚拟机栈,用一个stack表示
private Stack<StackFrame> stack = new Stack<>();

public ExecutorEngine() {

}

//开始执行的时候,传入main方法
public void execute(Method mainMethod) {
//执行一个函数,就要new一个函数栈帧
StackFrame stackFrame = StackFrame.create(mainMethod);
//把栈帧放入虚拟机栈
stack.push(stackFrame);

//当statck不为空时,开始循环执行
while (!stack.isEmpty()) {
//取出顶部栈帧
StackFrame frame = stack.peek();
//执行栈帧
ExecutionResult result = frame.execute();

//如果执行结果是,暂停当前栈帧,执行一个新的函数,就new一个新栈帧,(函数调用别的函数的情况)
if (result.isPauseAndRunNewFrame()) {
Method nextMethod = result.getNextMethod();
StackFrame nextFrame = StackFrame.create(nextMethod);
//设置调用他的函数栈帧
nextFrame.setCallerFrame(frame);
//设置传过去的参数,第一个参数都是this
setupFunctionCallParams(frame, nextFrame);
stack.push(nextFrame);
} else {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
* @author LZB
*/
public class Heap {

//堆,存放new出来的对象
private static Heap instance = new Heap();

private Heap() {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
import java.util.Map;

/**
* 自己定义一个Object代替java的Object
* @author LZB
*/
public class JavaObject {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,11 +17,13 @@ public class MethodArea {
public static final MethodArea instance = new MethodArea();

/**
* 注意:我们做了极大的简化, ClassLoader 只有一个, 实际JVM中的ClassLoader,是一个双亲委托的模型
* 这里ClassLoader 只有一个, 实际JVM中的ClassLoader,是一个双亲委托的模型,类装载器有命名空间,和被装载的类是关联的
*/

private ClassFileLoader clzLoader = null;

/**
* 保存load过的class,key:me/lzb/jvm/HourlyEmployee, value:ClassFile对象
*/
Map<String, ClassFile> map = new HashMap<>();

private MethodArea() {
Expand Down Expand Up @@ -58,24 +60,6 @@ public ClassFile findClassFile(String className) {
}


public Method getMethod(String className, String methodName, String paramAndReturnType) {

ClassFile clz = this.findClassFile(className);

Method m = clz.getMethod(methodName, paramAndReturnType);

if (m == null) {

throw new RuntimeException("method can't be found : \n"
+ "class: " + className
+ "method: " + methodName
+ "paramAndReturnType: " + paramAndReturnType);
}

return m;
}


public Method getMethod(MethodRefInfo methodRef) {

ClassFile clz = this.findClassFile(methodRef.getClassName());
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,12 +16,13 @@ public void run(String[] classPaths, String className) throws IOException {
loader.addClassPath(classPaths[i]);
}

//方法区,存放class文件,常量池
MethodArea methodArea = MethodArea.getInstance();

methodArea.setClassFileLoader(loader);

ExecutorEngine engine = new ExecutorEngine();

//获取构造函数名
className = className.replace(".", "/");

engine.execute(methodArea.getMainMethod(className));
Expand Down
Loading