view src/main/java/jp/ac/u_ryukyu/ie/cr/jungle/traverser/RedBlackTreeTraverser.java @ 308:201cc75a9984

change Red Black Tree Edit Path Extends
author tatsuki
date Thu, 26 Jan 2017 15:23:25 +0900
parents
children 2a0cb1f0ba4e
line wrap: on
line source

package jp.ac.u_ryukyu.ie.cr.jungle.traverser;

import jp.ac.u_ryukyu.ie.cr.jungle.core.Children;
import jp.ac.u_ryukyu.ie.cr.jungle.data.list.List;
import jp.ac.u_ryukyu.ie.cr.jungle.transaction.node.TreeNode;
import jp.ac.u_ryukyu.ie.cr.jungle.util.DefaultEither;
import jp.ac.u_ryukyu.ie.cr.jungle.util.Either;
import jp.ac.u_ryukyu.ie.cr.jungle.util.Error.Error;

import java.util.Iterator;

public class RedBlackTreeTraverser implements Traverser {
    @Override
    public Either<Error, Traversal> traverse(final TreeNode root, Evaluator evaluator) {
        Either<Error, List<Direction<TreeNode>>> ret = _traverse(root, evaluator, -1);

        if (ret.isA()) {
            return DefaultEither.newA(ret.a());
        }

        List<Direction<TreeNode>> list = ret.b();

        final Iterable<Direction<TreeNode>> iterable = list;
        final TreeNode destination = ret.b().head().getTarget();

        Traversal traversal = new Traversal() {
            @Override
            public Iterator<Direction<TreeNode>> iterator() {
                return iterable.iterator();
            }

            @Override
            public TreeNode destination() {
                return destination;
            }
        };

        return DefaultEither.newB(traversal);
    }

    private Either<Error, List<Direction<TreeNode>>> _traverse(TreeNode currentNode, Evaluator _evaluator, int pos) {
        Evaluation e = _evaluator.evaluate(currentNode, pos);
        Result r = e.result();
        if (r == Result.LEFT) {
            return left(currentNode, pos, e.evaluator());
        }

        if (r == Result.RIGHT) {
            return right(currentNode, pos, e.evaluator());
        }

        if (r == Result.GOAL) {
            return DefaultEither.newB(_goal(currentNode, pos));
        }


        return DefaultEither.newA(TraverserError.UNDEFINED_OPERATOR);
    }

    private List<Direction<TreeNode>> _goal(final TreeNode _current, final int _pos) {
        Direction<TreeNode> d = new Direction<TreeNode>() {
            @Override
            public int getPosition() {
                return _pos;
            }

            @Override
            public TreeNode getTarget() {
                return _current;
            }
        };

        List<Direction<TreeNode>> list = new List();
        List<Direction<TreeNode>> newList = list.addLast(d);

        return newList;
    }

    private <T extends TreeNode> Either<Error, List<Direction<TreeNode>>> left(final T _current, final int _pos, Evaluator _evaluator) {
        Children children = _current.getChildren();
        TreeNode child = children.at(0).b();
        Either<Error, List<Direction<TreeNode>>> either = _traverse(child, _evaluator, 0);
        if (either.isA()) {
            return either;
        }

        List<Direction<TreeNode>> list = either.b();
        Direction<TreeNode> d = new Direction<TreeNode>() {
            @Override
            public int getPosition() {
                return _pos;
            }

            @Override
            public T getTarget() {
                return _current;
            }
        };

        List<Direction<TreeNode>> newList = list.addLast(d);
        return DefaultEither.newB(newList);
    }

    private <T extends TreeNode> Either<Error, List<Direction<TreeNode>>> right(final T _current, final int _pos, Evaluator _evaluator) {
        Children children = _current.getChildren();
        TreeNode child = children.at(1).b();
        Either<Error, List<Direction<TreeNode>>> either = _traverse(_current, _evaluator, 1);
        if (either.isA()) {
            return either;
        }

        List<Direction<TreeNode>> list = either.b();
        Direction<TreeNode> d = new Direction<TreeNode>() {
            @Override
            public int getPosition() {
                return _pos;
            }

            @Override
            public T getTarget() {
                return _current;
            }
        };

        List<Direction<TreeNode>> newList = list.addLast(d);
        return DefaultEither.newB(newList);
    }
}