查找算法

查找就是根据给定的某个值,在查找表中确定一个其关键字等于给定值的数值元素。
查找表按照操作方式来分有两大种,静态查找表和动态查找表:
(1)静态查找表:只作查找操作的查找表,它主要操作有:
1、查询某个特定数据元素是否在查找表中;
2、检索某个特定数据元素和各种属性。
(2)动态查找表:在查找过程中同时插入查找表中不存在的数据元素,或者从查找表中删除已经存在的某个数据元素,它的主要操作有:
1、查找时插入数据元素;
2、查找时删除数据元素。

下面是几种普遍的查找算法以及其实现代码:

1、顺序表查找,线性查找,从第一个记录开始,逐个记录的关键字和给定值进行比较,若相等则查找成功,若直到最后一个都不等,则查找不成功。

//顺序查找法
    public static int Sqeuential_Search(int[] array,int key)
    {
        if (array==null||array.length<0)
            return 0;
        //结果为:查找成功则返回其位置,否则返回-1
        /*
        for (int i=0;i<array.length;i++)
        {
            if (array[i]==key)
                return i;
        }
        return -1;
        */
        //对顺序表查找进行优化操作,减少每次都需要对i比较是否越界的问题,可以在数组中放置一个哨兵
        array[0]=key;//作为哨兵,免去了每一次比较后都需要判断查找位置是否需要越界的小技巧
        int i=array.length-1;
        while (array[i]!=key)
            i--;
        return i;//若返回的是0就代表查找失败
    }

2、有序表查找,主要有折半查找或称为二分查找、插值查找以及斐波那契查找的实现代码

1、折半查找:又称二分查找,他的前提就是线性表中的记录必须是关键码有序,线性表必须采用顺序存储
  在有序变中,取中间记录作为比较对象,若相等则查找成功,若小于在左边查找,大于在右边查找
2、插值查表法:根据要查找的关键字key与查找表中最大最小记录的关键字比较之后的查找方法,关键在于适用于极端分布不均的数组中
middle=low+((key-arrays[low])/(arrays[high]-arrays[low]))*(high-low);//插值查表法
3、斐波那契查找:基于黄金分割原理
 public  static int BinarySearch(int[] arrays,int key)
    {
        int low=0;
        int high=arrays.length-1;
        int middle;//中位数
        while (low<=high)
        {
            //middle=low+(high-low)/2;//二分查找法
            middle=low+((key-arrays[low])/(arrays[high]-arrays[low]))*(high-low);//插值查表法
            if (arrays[middle]==key)
                return middle;
            else if (arrays[middle]>key)
            {
                high=middle-1;
            }
            else if (arrays[middle]<key)
                low=middle+1;
        }
        return 0;
    }
    //斐波那契查找
    //生成斐波那契数列
    public static int Fibonacci(int n)
    {
        if (n==0)
            return 0;
        if (n==1)
            return 1;
        else
            return Fibonacci(n-1)+Fibonacci(n-2);
    }
    //斐波那契查找
    public static int FibonacciSearch(int length,int key)
    {
        int low=0;
        int high=length-1;
        int middle,k=0;
        while (length>Fibonacci(k)-1)
            k++;//找到数组中个数在斐波那契数列中的位置
       for (int i=length-1;i<Fibonacci(k)-1;i++)
           arrays[i]=arrays[length-1];//将不满的位置补全

        while (low<=high)
        {
            middle=low+Fibonacci(k-1)-1;
            if (key<arrays[middle])
            {
                high=middle-1;
                k=k-1;
            }
            else if (key>arrays[middle])
            {
                low=middle+1;
                k=k-2;
            }
            else {
                if (middle<=length-1)
                    return middle;
                else
                    return length;
            }
        }
        return 0;
    }

3、线性索引查找

a. 稠密索引
b. 分块索引
c. 倒排索引

4、二叉树排序树
二叉排序树又称为二叉查找树,具有以下性质:
a、若它的左子树不空,则左子树所有结点的值均小于它的根结构的值;
b、若它的右子树不空,则右子树上所有结点的值均大于它的根结点的值。
c、它的左、右子树也分别为二叉排序树。

  /**
     * 二叉树排序树查找:二叉排序树即表示所有的左孩子都比根结点小,右孩子都比根结点大
     */
    public static class BiTNodeNew
    {
        int data;
        BiTNodeNew leftchild;
        BiTNodeNew rightchild;
        public BiTNodeNew(int data,BiTNodeNew leftchild,BiTNodeNew rightchild)
        {
            this.data=data;
            this.leftchild=leftchild;
            this.rightchild=rightchild;
        }
    }
    //创建一个二叉排序树
    public static BiTNodeNew CreateBinarySortTree(int[] arrays)
    {
        BiTNodeNew root;
        root=new BiTNodeNew(arrays[0],null,null);
        //将数组插入到二叉树中,建立二叉排序树
        for (int i=1;i<arrays.length;i++)
            InsertSortTree(root,arrays[i]);
        return root;
    }
    public static void InsertSortTree(BiTNodeNew root,int number)
    {
       BiTNodeNew temp;
        while (true)
        {//对二叉排序树进行插入操作
            temp=new BiTNodeNew(number,null,null);
            if (root.data==number)
                return;
            if (root.data>number)
            {
                //若输入的数小于根结点的值
                if (root.leftchild==null)
                {
                    root.leftchild = temp;
                    return;
                }
                else
                    root=root.leftchild;
            }else
            {
                if (root.rightchild==null)
                {
                    root.rightchild=temp;
                    return;
                }
                else
                    root=root.rightchild;
            }
        }
    }
    public static boolean SearchBST(BiTNodeNew tree,int key)
    {
        if (tree==null)//若为空树查找不成功
            return false;
        else if (tree.data==key)
            return true;
        else if (key<tree.data)
        {
            return SearchBST(tree.leftchild,key);//在左子树中查找
        }
        else
            return SearchBST(tree.rightchild,key);//右子树中查找
    }
    //二叉排序树插入操作,当二叉排序树中不存在关键字时就将key值插入到合适的位置中去
    //插入成功即返回true,否则返回false
    public static boolean InsertBST(BiTNodeNew root,int key)
    {
        BiTNodeNew temp;
        if (!SearchBST(root,key))
        {//若查找不成功
            InsertSortTree(root,key);
            return true;
        }
        else
            return false;
    }
    /**
     * 二叉树的删除操作,三种情况的分析
     *     1、叶子结点
     *     2、仅有左子树和右子树的结点
     *     3、左右子树都有的结点
     */
    public static boolean  DeleteBST(BiTNodeNew root,int key)
    {
        if (root==null)
            return false;
        else
        {
            if (key==root.data)
            {
                return Delete(root);
            }
            else if (key<root.data)
            //递归实现删除
                return DeleteBST(root.leftchild,key);
            else
                return DeleteBST(root.rightchild,key);
        }
    }
    public static boolean Delete(BiTNodeNew biTNodeNew)
    {
        BiTNodeNew temp=biTNodeNew;
        //分三种情况考虑
        if (biTNodeNew.leftchild==null&&biTNodeNew.rightchild==null)
            biTNodeNew=null;
        else if (biTNodeNew.leftchild==null)
        {
            //左子树为空的话,只需要将右子树赋给原结点,并将原结点删除
            //temp=biTNodeNew;
            temp=temp.rightchild;
        }
        else if (biTNodeNew.rightchild==null)
        {//右子树为空的时候
           // temp=biTNodeNew;
            temp=temp.leftchild;
        }
        else
        {
            //考虑左右子树都不为空的时候删除操作
           // temp=biTNodeNew;
            BiTNodeNew nodeNew=biTNodeNew;
            nodeNew=nodeNew.leftchild;
            while (nodeNew.rightchild!=null)
            {
                temp=nodeNew;
                nodeNew = nodeNew.rightchild;//找到左边最接近该结点的值
            }
            biTNodeNew.data=nodeNew.data;
            if (temp!=biTNodeNew)
                temp.rightchild=nodeNew.leftchild;//重接temp的右子树
            else
            {
                temp.leftchild=nodeNew.leftchild;
            }
        }
        return true;
    }  
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值