折半查找 (二分查找)
//折半查找
public class BinarySearch {
public int binarySearch(int[] arr, int n, int key){
int low=1;//从1开始
int high=n;
while(low<=high){
int mid = (low+high)/2;
if (arr[mid]<key) {
low=mid+1;//进入右半区继续查找
}else if (arr[mid]>key) {
high=mid-1;//进入左半区继续查找
}else {
return mid;
}
}
return 0;
}
public static void main(String[] args) {
int[] arr = {0,1,16,24,35,47,59,62,73,88,99};
int n=arr.length-1;
int key=62;
BinarySearch aSearch = new BinarySearch();
System.out.println(aSearch.binarySearch(arr, n, key));
}
}
二叉树查找
package Search;
/**
* 二叉排序树(二叉查找树)
* 若是泛型,则要求满足T extends Comparable<T> static问题
* @author Yongh
*
*/
class Node {
int data;
Node lChild, rChild;
public Node(int data) {
this.data = data;
lChild = null;
rChild = null;
}
}
public class BSTree {
private Node root;
public BSTree() {
root = null;
}
/*
* 查找
*/
public boolean SearchBST(int key) {
return SearchBST(key, root);
}
private boolean SearchBST(int key, Node node) {
if (node == null)
return false;
if (node.data == key) {
return true;
} else if (node.data < key) {
return SearchBST(key, node.rChild);
} else {
return SearchBST(key, node.lChild);
}
}
/*
* 查找,非递归
*/
public boolean SearchBST2(int key) {
Node p = root;
while (p != null) {
if (p.data > key) {
p = p.lChild;
} else if (p.data < key) {
p = p.rChild;
} else {
return true;
}
}
return false;
}
/*
* 插入,非递归
*/
public boolean InsertBST(int key) {
Node newNode = new Node(key);
if (root == null) {
root = newNode;
return true;
}
Node f = null; // 指向父结点
Node p = root; // 当前结点的指针
//找准插入的位置
while (p != null) {
if (p.data > key) {
f = p;
p = p.lChild;
} else if (p.data < key) {
f = p;
p = p.rChild;
} else {
System.out.println("数据重复,无法插入!");
return false;
}
}
//找到不为null的位置了,比较大小再插入值
if (f.data > key) {
f.lChild = newNode;
} else if (f.data < key) {
f.rChild = newNode;
}
return true;
}
/**
*
* 插入方法 非递归
*
*/
public void insert(int data){
Node newNode = new Node(data);
if (root==null) {
root = newNode;
return;
}else{
Node current = root;
Node parent;
while(true){
parent = current;
if (data < current.data) {
current = current.lChild;
if (current == null) {
parent.lChild = newNode;
return;
}
}else {
current = current.rChild;
if (current == null) {
parent.rChild = newNode;
return;
}
}
}
}
}
/*
* 插入,参考别人博客,递归
* 思路:类似查找,
* 但若方法中的node为null的话,将无法插入新数据,需排除null的情况
*/
public boolean InsertBST2(int key) {
if (root == null) {
root = new Node(key);
return true;
}
return InsertBST2(key, root);
}
private boolean InsertBST2(int key, Node node) {
if (node.data > key) {
if (node.lChild == null) { // 有null的情况下,才有父结点
node.lChild = new Node(key);
return true;
} else {
return InsertBST2(key, node.lChild);
}
} else if (node.data < key) {
if (node.rChild == null) {
node.rChild = new Node(key);
return true;
} else {
return InsertBST2(key, node.rChild);
}
} else {
System.out.println("数据重复,无法插入!");
return false;
}
}
/*
* 这样的插入是错误的(node无法真正被赋值)
*/
/*
private boolean InsertBST2(int key, Node node) {
if(node!=null) {
if (node.data > key)
return InsertBST2(key, node.lChild);
else if (node.data < key)
return InsertBST2(key, node.rChild);
else
return false;//重复
}else {
node=new Node(key);
return true;
}
}
*/
/*
* 删除操作,先找到删除结点位置及其父结点
* 因为需要有父结点,所以暂时没想到递归的方法(除了令Node对象带个parent属性)
*/
public boolean deleteBST(int key) {
if (root == null) {
System.out.println("空表,删除失败");
return false;
}
Node f = null; // 指向父结点
Node p = root; // 指向当前结点
while (p != null) {
if (p.data > key) {
f = p;
p = p.lChild;
} else if (p.data < key) {
f = p;
p = p.rChild;
} else {
delete(p, f);
System.out.println("删除成功!");
return true;
}
}
System.out.println("该数据不存在");
return false;
}
/*
* 删除结点P的操作
* 必须要有父结点,因为Java无法直接取得变量p的地址(无法使用*p=(*p)->lChild)
*/
private void delete(Node p, Node f) {// p为删除结点,f为其父结点
if (p.lChild == null) { // 左子树为空,重接右子树
if (p == root) { // 被删除结点为根结点,该情况不能忽略
root = root.rChild;
p = null;
} else {
if (f.data > p.data) { // 被删结点为父结点的左结点,下同
f.lChild = p.rChild;
p = null; // 释放结点别忘了
} else {// 被删结点为父结点的右结点,下同
f.rChild = p.rChild;
p = null;
}
}
} else if (p.rChild == null) { // 右子树为空,重接左子树
if (p == root) { // 被删除结点为根结点
root = root.lChild;
p = null;
} else {
if (f.data > p.data) {
f.lChild = p.lChild;
p = null;
} else {
f.rChild = p.lChild;
p = null;
}
}
} else { // 左右子树都不为空,删除位置用前驱结点替代
Node q, s;
q = p;
s = p.lChild;
while (s.rChild != null) { // 找到待删结点的最大前驱s
q = s;
s = s.rChild;
}
p.data = s.data; // 改变p的data就OK
if (q != p) {
q.rChild = s.lChild;
} else {
q.lChild = s.lChild;
}
s = null;
}
}
/*
* 中序遍历
*/
public void inOrder() {
inOrder(root);
System.out.println();
}
public void inOrder(Node node) {
if (node == null)
return;
inOrder(node.lChild);
System.out.print(node.data + " ");
inOrder(node.rChild);
}
/*
* 测试代码
*/
public static void main(String[] args) {
BSTree aTree = new BSTree();
BSTree bTree = new BSTree();
int[] arr = { 62, 88, 58, 47, 35, 73, 51, 99, 37, 93 };
for (int a : arr) {
aTree.InsertBST(a);
bTree.InsertBST2(a);
}
aTree.inOrder();
bTree.inOrder();
System.out.println(aTree.SearchBST(35));
System.out.println(bTree.SearchBST2(99));
aTree.deleteBST(47);
aTree.inOrder();
}
}