各种查找的实现Java

/**
 * 待排序记录类
 * @author liangxiamoyi
 *
 */
public class Element {
	/**
	 * 数据
	 */
	private int key;
	/**
	 * 获得数据
	 * @return key值
	 */
	public int getKey(){
		return key;
	}
	/**
	 * 设置数据值
	 * @param key 数据值
	 */
	public void setKey(int key){
		this.key=key;
	}
}

import java.util.Scanner;

/**
 * 查找方法类
 * @author liangxiamoyi
 *
 */
public class Search {
	/**
	 * 顺序查找
	 * @param r 待查找文件
	 * @param n 个数
	 * @param k 查找的元素
	 * @return 成功返回k所在的位置,不成功返回0
	 */
	public static int seqSearch(Element[] r,int n,int k){
		int i=1;
		while(i<=n&&r[i].getKey()!=k){
			i++;
		}
		if(i>n)return 0;
		return i;
	}
	/**
	 * <p>快速查找,引入一个“虚拟”记录r[n+1],提高算法查找效率</p>
	 * <p>加速原理:当算法的一个内循环要测试两个或多个条件时,应力图将其减少成一个条件</p>
	 * <p>算法quickSearch比seqSearch节省20%的运行时间</p>
	 * @param r 待查找文件
	 * @param n 个数
	 * @param k 查找元素
	 * @return 成功返回k所在的位置,不成功返回0
	 */
	public static int quickSearch(Element[] r,int n,int k){
		int i=1;
		r[n+1].setKey(k);
		while(r[i].getKey()!=k){
			i++;
		}
		if(i<=n)return i;
		return 0;
	}
	/**
	 * <p>更快速的查找</p>
	 * <p>算法quickerSearch比quickSearch总比较次数减少了10%,运行时间减少了30%</p>
	 * @param r 待查找文件
	 * @param n 个数
	 * @param k 查找元素
	 * @return 成功返回k的位置,不成功返回0
	 */
	public static int quickerSearch(Element[] r,int n,int k){
		int i=-1;
		r[n+1].setKey(k);
		i+=2;
		while(r[i].getKey()!=k){
			if(r[i+1].getKey()!=k)i+=2;
			else {
				i++;
				break;
			}
		}
		if(i<=n)return i;
		else return 0;
	}
	/**
	 * <p>有序表的顺序查找,设定一个虚拟记录r[n+1]=MAX_VALUE</p>
	 * <p>该算法能更快地确定一个记录不存在</p>
	 * @param r 待查找的文件
	 * @param n 个数
	 * @param k 查找元素
	 * @return 成功返回k的位置,不成功返回0 
	 */
	public static int sortedSearch(Element[] r,int n,int k){
		int i=1;
		r[n+1].setKey(Integer.MAX_VALUE);
		while(r[i].getKey()<k){
			i++;
		}
		if(r[i].getKey()==k)return i;
		else return 0;
	}
	/**
	 * 对半查找
	 * @param r 待查找文件
	 * @param n 个数
	 * @param k 查找元素
	 * @return 成功返回k的位置,不成功返回0
	 */
	public static int binSearch(Element[] r,int n,int k){
		int i,s=1,e=n;
		while(s<=e){
			i=(s+e)/2;
			if(k<r[i].getKey())e=i-1;
			if(k>r[i].getKey())s=i+1;
			if(k==r[i].getKey())return i;
		}
		return 0;
	}
	/**
	 * 一致对半查找,若n为偶数,则算法有时将涉及一个r[0]=MIN_VALUE
	 * <p>相比于对半查找,由三个游标变为两个游标</p>
	 * @param r 待查找文件
	 * @param n 个数
	 * @param k 查找元素
	 * @return 成功返回k的位置,不成功返回0
	 */
	public static int unanBinSearch(Element[] r,int n,int k){
		int i=(n+1)/2;
		int m=n/2;
		r[0].setKey(Integer.MIN_VALUE);
		while(k!=r[i].getKey()){
			if(k<r[i].getKey()){
				if(m==0)return 0;
				else {
					i-=(m+1)/2;
					m=m/2;
				}
			}
			if(k>r[i].getKey()){
				if(m==0)return 0;
				else {
					i+=(m+1)/2;
					m=m/2;
				}
			}	
		}
		return i;
	}
	/**
	 * 计算delta数组
	 * @param delta 辅助表
	 * @param n 个数
	 */
	public static void calDelta(int[] delta,int n){
		int k=(int)(Math.log(n)/Math.log(2))+2;
		int s=1;//累积存储2的j-1次方,初始为2的0次方,故为1
		for(int j=1;j<=k;j++){
			delta[j]=(n+s)/(s*2);
			s*=2;
		}
	}
	/**
	 * 使用辅助表的一致对半查找
	 * <p>该算法和算法unanBinSearch相似,但它使用一个辅助表来代替涉及m的计算</p>
	 * <p>辅助表的项是DELTA[j]=(N+2^(j-1))/2^j向下取整</p>
	 * @param r 待查找文件
	 * @param n 个数
	 * @param k 查找元素
	 * @param delta 辅助表
	 * @return 成功返回k的位置,不成功返回0
	 */
	public static int conBinSearch(Element[] r,int n,int k,int[] delta){
		int i=delta[1],j=2;
		while(k!=r[i].getKey()){
			if(k<r[i].getKey()){
				if(delta[j]==0)return 0;
				else {
					i-=delta[j];
					j++;
				}
			}
			if(k>r[i].getKey()){
				if(delta[j]==0)return 0;
				else {
					i+=delta[j];
					j++;
				}
			}	
		}
		return i;
	}
	/**
	 * 构造斐波那契数列
	 * @param f 存储数列的数组
	 * @param n 文件个数
	 */
	public static void fibonacci(int[] f,int n){
		f[0]=0;
		f[1]=1;
		f[2]=1;
		int i=2;
		while(f[i]<n){
			f[i+1]=f[i]+f[i-1];
			i=i+1;
		}
	}
	/**
	 * 斐波那契查找,算法假定n+1是一个斐波那契数,即n+1=f[m+1]
	 * <p>T(k)表示k阶斐波那契树,若k=0或1则此树就是0;若k>=2;则树T(k)根为f[k].</p>
	 * <p>左子树为T[k-1],右子树为阶数为k-2且所有结点之编号都增加f[k]的斐波那契树</p>
	 * @param r 待查找文件
	 * @param m 个数
	 * @param k 查找元素
	 * @param fib 存放Fibonacci序列的数组
	 * @return 成功返回k的位置,不成功返回0
	 */
	public static int fibSearch(Element[] r,int m,int k,int[] fib){
		int i=fib[m],p=fib[m-1],q=fib[m-2];
		int t;
		while(k!=r[i].getKey()){
			if(k<r[i].getKey()){
				if(q==0)return 0;
				else {
					i-=q;
					t=p;
					p=q;
					q=t-p;
				}
			}
			if(k>r[i].getKey()){
				if(p==1)return 0;
				else{
					i+=q;
					p-=q;
					q-=p;
				}
			}
		}
		return i;
	}
	/**
	 * 插值查找,表中关键词已为增序,且在(k[0],k[n+1])之间均匀分布
	 * @param r 待查找文件
	 * @param n 个数
	 * @param k 查找元素
	 * @return 成功返回k的位置,不成功返回0
	 */
	public static int  interSearch(Element[] r,int n,int k){
		int s=0,e=n+1;//s和e表示当前查找子表的下限和上限
		int i;
		while(e-s>1){
			//k的期望值
			i=(int)(Math.ceil(s+1.0*(k-r[s].getKey())/(r[e].getKey()-r[s].getKey())*(e-s-1)));
			if(k<r[i].getKey())e=i;
			if(k>r[i].getKey())s=i;
			if(k==r[i].getKey())return i;
		}
		return 0;
	}
	public static void main(String[] args){
		int num;
		Scanner s=new Scanner(System.in);
		System.out.println("请输入文件个数:");
		num=s.nextInt();
		Element[] e=new Element[num+2];
		System.out.println("请依次输入文件关键词:");
		e[0]=new Element();
		e[0].setKey(0);
		e[num+1]=new Element();
		e[num+1].setKey(13);
		for(int i=1;i<num+1;i++){
			e[i]=new Element();
			e[i].setKey(s.nextInt());
		}
		System.out.println("请输入你要查找的文件关键词:");
		System.out.println(Search.interSearch(e, num, s.nextInt()));
		System.out.println(Search.seqSearch(e, num, s.nextInt()));
		System.out.println(Search.quickSearch(e, num, s.nextInt()));
		System.out.println(Search.quickerSearch(e, num, s.nextInt()));
		System.out.println(Search.sortedSearch(e, num, s.nextInt()));
		System.out.println(Search.binSearch(e, num, s.nextInt()));
		System.out.println(Search.unanBinSearch(e, num, s.nextInt()));
		int[] delta=new int[num];
		Search.calDelta(delta, num);
		System.out.println(Search.conBinSearch(e, num, s.nextInt(), delta));
		int[] fib=new int[num];
		Search.fibonacci(fib, num);
		int m=0;
		while(fib[m+1]-1!=num){
			m++;
		}
		System.out.println(Search.fibSearch(e, m, s.nextInt(), fib));
	}
}

测试结果:


  • 3
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
好的,下面是一份基本的二叉查找树的 Java 实现代码: ``` public class BinarySearchTree { private Node root; private class Node { private int key; private Node left; private Node right; public Node(int key) { this.key = key; this.left = null; this.right = null; } } public BinarySearchTree() { root = null; } public void insert(int key) { root = insert(root, key); } private Node insert(Node node, int key) { if (node == null) { node = new Node(key); return node; } if (key < node.key) { node.left = insert(node.left, key); } else if (key > node.key) { node.right = insert(node.right, key); } return node; } public void delete(int key) { root = delete(root, key); } private Node delete(Node node, int key) { if (node == null) { return null; } if (key < node.key) { node.left = delete(node.left, key); } else if (key > node.key) { node.right = delete(node.right, key); } else { if (node.left == null) { return node.right; } else if (node.right == null) { return node.left; } node.key = findMin(node.right).key; node.right = delete(node.right, node.key); } return node; } private Node findMin(Node node) { while (node.left != null) { node = node.left; } return node; } public boolean search(int key) { return search(root, key); } private boolean search(Node node, int key) { if (node == null) { return false; } if (key == node.key) { return true; } else if (key < node.key) { return search(node.left, key); } else { return search(node.right, key); } } public void inorderTraversal() { inorderTraversal(root); } private void inorderTraversal(Node node) { if (node != null) { inorderTraversal(node.left); System.out.print(node.key + " "); inorderTraversal(node.right); } } } ``` 这份代码实现了二叉查找树的基本操作,包括插入、删除、搜索和中序遍历。你可以根据自己的需求进行修改和拓展。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值