package lengreen.struct.other;
import lengreen.struct.Strategy;
import lengreen.struct.impl.BinaryTreeNode;
import lengreen.struct.impl.IntegerStrategy;
import lengreen.struct.util.BinaryTreeUtil;
public class Search {
private static BinaryTreeNode root;
private static Strategy strategy = new IntegerStrategy();
public static void main(String[] args) throws Exception {
int[] a = { 1, 3, 5, 7, 9, 11, 13, 15 };
// int end = order(a, 7);
// int end = binRecursion(a, 7, 0, a.length - 1);
int end = bin(a, 7);
System.out.println("所要查找的数所在位置为:" + end);
// 二叉树查找
genRoot();
BinaryTreeNode res = binTree(root, 1);
System.out.println(res.getData());
}
// 顺序查找
public static int order(int[] array, int tar) {
for (int i = 0; i < array.length; i++) {
if (tar == array[i]) {
return i + 1;
}
}
return -1;
}
// 二分法查找递归
public static int binRecursion(int[] array, int tar, int low, int high) {
int mid;
if (low > high) {
return -1;
}
mid = (high + low) / 2;
if (tar == array[mid]) {
return mid + 1;
} else if (tar > array[mid]) {
binRecursion(array, tar, mid++, high);
} else {
binRecursion(array, tar, low, mid--);
}
return -1;
}
// 二分法查找非递归
public static int bin(int[] array, int tar) {
int low = 0, high = array.length - 1, mid;
while (low <= high) {
mid = (low + high) / 2;
if (array[mid] == tar) {
return mid + 1;
} else if (array[mid] < tar) {
low = mid + 1;
} else {
high = mid - 1;
}
}
return -1;
}
// 二叉树递归查找算法
public static BinaryTreeNode binTreeRecusion(BinaryTreeNode bt, Object tar) {
if (bt == null) {
return new BinaryTreeNode("null");
}
switch (strategy.compare(tar, bt.getData())) {
case -1:// tar比data小就查找左子树
return binTree(bt.getLeftChild(), tar);
case 1:// tar比data大就查找右子树
return binTree(bt.getRightChild(), tar);
default:// 比较结果是0,tar和data相等就返回
return bt;
}
}
// 二叉树非递归查找算法
public static BinaryTreeNode binTree(BinaryTreeNode bt, Object tar) {
while (bt != null) {
switch (strategy.compare(tar, bt.getData())) {
case -1:// tar比data小就查找左子树
return bt = bt.getLeftChild();
case 1:// tar比data大就查找右子树
return bt = bt.getRightChild();
default:// 比较结果是0,tar和data相等就返回
return bt;
}
}
return new BinaryTreeNode("null");
}
// 二叉树插入新元素算法
public static void insertBinTree(Integer tar) {
BinaryTreeNode current = root;
BinaryTreeNode tmp = null;
while (current != null) {
tmp = current;
if (strategy.compare(tar, current.getData()) < 0) {
current = current.getLeftChild();
} else {
current = current.getRightChild();
}
}
if (tmp == null) {// 说明被插入树为空树
root = new BinaryTreeNode(tar);
} else if (strategy.compare(tar, tmp.getData()) < 0) {
tmp.setLeftChild(new BinaryTreeNode(tar));
} else {
tmp.setRightChild(new BinaryTreeNode(tar));
}
}
// 二叉树删除元素算法
public static Object remove(Integer tar) {
BinaryTreeNode val = binTree(root, tar);
if (val == null) {
return null;
}
BinaryTreeNode del = null;
BinaryTreeNode subTree = null;// 缓存子树
if (!val.hasLeftChild() || !val.hasRightChild()) {
del = val;
} else {
del = BinaryTreeUtil.getPredecessor(val);
Object tmp = val.getData();// 交换要删除的数据
val.setData(del.getData());
del.setData(tmp);
}
// 此时待删结点只有左子树或右子树
if (del.hasLeftChild()) {
subTree = del.getLeftChild();
} else {
subTree = del.getRightChild();
}
if (del == root) { // 若待删结点为根
if (subTree != null)
subTree.sever();
root = subTree;
} else if (subTree != null) {// del 为非叶子结点
if (del.isLeftChild())
del.getParent().setLeftChild(subTree);
else
del.getParent().setRightChild(subTree);
} else {// del 为叶子结点
del.sever();
}
return del.getData();
}
private static void genRoot() {
root = new BinaryTreeNode(7);
// 左子树左右节点
BinaryTreeNode a2 = new BinaryTreeNode(2);
BinaryTreeNode a3 = new BinaryTreeNode(3);
BinaryTreeNode a4 = new BinaryTreeNode(4);
BinaryTreeNode a6 = new BinaryTreeNode(6);
// 右子树所有节点
BinaryTreeNode a9 = new BinaryTreeNode(9);
BinaryTreeNode a13 = new BinaryTreeNode(13);
BinaryTreeNode a15 = new BinaryTreeNode(15);
BinaryTreeNode a17 = new BinaryTreeNode(17);
BinaryTreeNode a18 = new BinaryTreeNode(18);
BinaryTreeNode a20 = new BinaryTreeNode(20);
// 根节点
root.setLeftChild(a3);
root.setRightChild(a17);
// 左子树
a3.setLeftChild(a2);
a3.setRightChild(a4);
a4.setRightChild(a6);
// 右子树
a17.setLeftChild(a13);
a17.setRightChild(a20);
a13.setLeftChild(a9);
a13.setRightChild(a15);
a20.setLeftChild(a18);
}
}
二叉树
package lengreen.struct.util;
import lengreen.struct.Node;
import lengreen.struct.impl.BinaryTreeNode;
public class BinaryTreeUtil {
// 最小值
public static Node min(BinaryTreeNode v) {
if (v != null)
while (v.hasLeftChild())
v = v.getLeftChild();
return v;
}
// 最大值
public static Node max(BinaryTreeNode v) {
if (v != null)
while (v.hasRightChild())
v = v.getRightChild();
return v;
}
// 后续节点
public static BinaryTreeNode getSuccessor(BinaryTreeNode v) {
if (v == null)
return null;
if (v.hasRightChild())
return (BinaryTreeNode) min(v.getRightChild());
while (v.isRightChild())
v = v.getParent();
return v.getParent();
}
// 前驱节点
public static BinaryTreeNode getPredecessor(BinaryTreeNode v) {
if (v == null)
return null;
if (v.hasLeftChild())
return (BinaryTreeNode) max(v.getLeftChild());
while (v.isLeftChild())
v = v.getParent();
return v.getParent();
}
}
工具类