zoukankan      html  css  js  c++  java
  • 基础算法-查找:折半查找

    折半查找

    又称为二分查找。这种查找方法要求查找表的数据是线性结构保存,并且还要求查找表中的数据是按关键字由小到大有序排列。

    折半查找(二分查找)是一种简单而又高效的查找算法,其查找长度至多为㏒2n+1(判定树的深度),平均查找长度为㏒2(n+1)-1,效率比顺序查找要高,但折半查找只能适用于顺序存储有序表(如对线性链表就无法有效地进行折半查找)。

    经典非递归算法实现

    int Binary_Search(int search_table[], int key, int low ,int high)
    {
    	while(low <= high)
    	{
    		mid  = (low + high) / 2;
    		if(search_table[mid] < key)
    		{
    			low = mid + 1;
    		}
    		else if(search_table[mid] > key)
    		{
    			high = mid - 1;
    		}
    		else
    		{
    			return mid;
    		}
    	}//while
    	
    	return -1;
    }
    

    经典递归算法实现

    int Binary_Search(int search_table[], int key, int low ,int high)
    {
    	if(low > high)
    	{
    		return -1;
    	}
    	int mid = (low + high) / 2;
    	
    	if(search_table[mid] == key)
    	{
    		return mid;
    	}
    	else if(search_table[mid] < key)
    	{
    		Binary_Search(search_table, key, mid + 1, high);
    	}
    	else
    	{
    		Binary_Search(search_table, key, low, mid - 1);
    	}
    }
    

      不过,由于折半查找的前提条件是需要有序表顺序存储,对于静态查找表,一次排序后不再变化,这样的算法已经比较好了。但是对于频繁执行插入或删除操作的数据集来说,维护有序的排序会带来不小的工作量,那就不建议使用了。

    说一个小的知识点:

    mid = (first + last) / 2;
    //等价于
    mid = first + (last - first) / 2;
    

    如果把一个有序的线性数组放到一个二维数组中,那么同样可以利用二分查找:

    在这个数组上面查找

    bool searchMatrix(vector<vector<int>>& matrix, int target) 
    {
    	bool found = false;
    	int m = matrix.size();//行数
    	int n = matrix[0].size();//列数
    	
    	int first = 0;
    	int last = m * n - 1;
    	
    	while(first <= last)
    	{
    		int mid = (first + last) / 2;
    		
    		if(matrix[mid / n][mid % n] == target)
    		{
    			found = true;
    			break;
    		}
    		else if(matrix[mid / n][mid % n] > target)
    		{
    			last = mid - 1;
    		}
    		else
    		{
    			first = mid + 1;
    		}
    		
    	}//while
    	
    	return found;
    }  

    折半查找扩展

     折半查找的思想其实就是,每次查找之后,能缩小下次查找的范围,这一点很重要。以后所有的查找问题,只要是在有序的线性表上查找或者半有序的线性表上查找,都要往折半查找上靠拢,想着每次查找之后,能缩小下次查找的范围。

    在一个二维数组中,每一行都按照从左到右递增的顺序排序,每一列都按照从上到下递增的顺序排序。
    请完成一个函数,输入这样的一个二维数组和一个整数,判断数组中是否含有该整数。
    

      只要遇到了有序的查找,就往折半查找上想办法,同时想着怎么能缩小下次查找的范围。

    bool searchMatrix(vector<vector<int>>& matrix, int target) 
    {
    	int row = matrix.size();
    	int column = matrix[0].size();
    	
    	bool found = false;
    	
    	int i = 0;
    	int j = column - 1;
    	while(i < row && j >= 0)
    	{
    		if(matrix[i][j] > target)
    		{
    			--j;
    		}
    		else if(matrix[i][j] < target)
    		{
    			++i;
    		}
    		else
    		{
    			found = true;
    			break;
    		}
    	}//while
    	
    	return found;
    }
    

      这里存储二维数组用的是vector,当然也可以用一个int类型的指针,然后通过行数和列数访问二维数组每一个元素。

  • 相关阅读:
    View Focus的处理过程及ViewGroup的mFocused字段分析
    Android按键事件处理流程 -- KeyEvent
    Android中将xml布局文件转化为View树的过程分析(下)-- LayoutInflater源码分析
    Android中将xml布局文件转化为View树的过程分析(上)
    IntentService源码分析
    Android源码分析之SharedPreferences
    进程间传递文件描述符
    Epoll在LT和ET模式下的读写方式
    gdb
    Android开发之漫漫长途 Fragment番外篇——TabLayout+ViewPager+Fragment
  • 原文地址:https://www.cnblogs.com/stemon/p/4475792.html
Copyright © 2011-2022 走看看