二分查找的递归和非递归写法

一、概述

二分查找是针对有序数列的,对无序数列是无效的,在有序序列中使用二分查找能大大提高查找效率,通常能将时间按复杂度从O(n)降至O(logn)。

二、查找某数的位置(或存在性)

递归:

 1 //返回"-1"表示为找到
 2 //否则返回目标的下标(若有多个,只是其中一个)
 3 int binary_searchs(int *arr, int target, int l, int r)
 4 {
 5     if (l > r)  return -1;
 6     int mid = (l + r) >> 1;
 7     if (arr[mid] == target)
 8         return mid;
 9     else if (arr[mid] > target)
10         binary_search(arr, target, l, mid - 1);
11     else
12         binary_search(arr, target, mid + 1, r);
13 }

非递归:

 1 //返回"-1"表示为找到
 2 //否则返回目标的下标(若有多个,只是其中一个)
 3 int binary_searchs(int * arr, int x, int l, int r)
 4 {
 5     int lt = l, rt = r;
 6     while (lt <= rt)
 7     {
 8         int mid = (lt + rt) >> 1;
 9         if (arr[mid] == x)  return mid;
10         else if (arr[mid] < x)
11             lt = mid + 1;
12         else
13             rt = mid - 1;
14     }
15     return -1;
16 }

三、查找某数出现的次数

递归:

 1 //返回target的出现次数
 2 //返回0意味着不存在
 3 int binary_search(int *arr, int target, int l, int r)
 4 {
 5     if (l > r)  return 0;
 6     int mid = (l + r) >> 1;
 7     if (arr[mid] == target)
 8         return 1 + binary_search(arr, target, l, mid - 1) + binary_search(arr, target, mid + 1, r);
 9     else if (arr[mid] > target)
10         binary_search(arr, target, l, mid - 1);
11     else
12         binary_search(arr, target, mid + 1, r);
13 }

递归(优化版):如果有序数列中,目标元素占大多数,二分法会退化成逐一遍历,O(logn)增至O(n),我们要预防这种情况,所以当找到目标元素时,尽可能向两边去找目标元素。

 1 //返回target的出现次数
 2 //返回0意味着不存在
 3 int binary_search(int *arr, int target, int l, int r)
 4 {
 5     if (l > r)  return 0;
 6     int mid = (l + r) >> 1;
 7     if (arr[mid] == target)
 8     {
 9         int cnt1, cnt2;
10         cnt1 = cnt2 = mid;
11         if (((cnt1 - 1) >= l) && (arr[cnt1] == arr[cnt1 - 1]))  cnt1--;
12         if (((cnt2 + 1) <= r) && (arr[cnt2] == arr[cnt2 + 1]))  cnt2++;
13         return 1 + (cnt2 -cnt1) + binary_search(arr, target, l, cnt1 - 1) + binary_search(arr, target, cnt2 + 1, r);
14     }
15     else if (arr[mid] > target)
16         binary_search(arr, target, l, mid - 1);
17     else
18         binary_search(arr, target, mid + 1, r);
19 }

非递归:我觉得这个非递归不好写,主要是找到目标元素时,在前一部分和后一部分也有可能存在目标元素,不用递归的方式不好写。以后写出来了再来补吧。

原文地址:https://www.cnblogs.com/lfri/p/9326255.html

时间: 2024-10-01 07:28:03

二分查找的递归和非递归写法的相关文章

二分查找算法(递归与非递归两种方式)

首先说说二分查找法. 二分查找法是对一组有序的数字中进行查找,传递相应的数据,进行比较查找到与原数据相同的数据,查找到了返回1,失败返回对应的数组下标. 采用非递归方式完成二分查找法.java代码如下所示. /* * 非递归二分查找算法 * 参数:整型数组,需要比较的数. */ public static int binarySearch(Integer[]srcArray,int des){ //第一个位置. int low=0; //最高位置.数组长度-1,因为下标是从0开始的. int h

二分查找的循环实现和递归实现

自己实现了二分查找的循环实现和递归实现 说明:二分查找适用于顺序存储结构,不适于链式存储结构,是一个高效的查找方法.虽然折半查找效率高,但是要排序,排序本身是一种很费时的运算. 要求传入的表是有序的. 二分查找的过程可用二叉树描述,把当前区间的中点位置上的元素作为根,左子表和右子表中的元素分别作为根的左子树和右子树,由此得到二叉树. 此树称为描述折半查找的判定树或比较树. package lirui.find; /** * Created by lirui on 14-8-14. */ publ

二叉树的递归和非递归遍历

// 本次练习的是  二叉树的  递归和非递归  遍历   以及二叉树的  节点数  高度  叶子节点数   和查找功能  //如果要是变量在函数栈回归时不回归原值,则可以用引用// #define _CRT_SECURE_NO_WARNINGS 1#include<iostream>#include<stack>#include<queue>using namespace std; template<class T>struct BinaryTreeNod

数据结构之关于树的操作(树的递归和非递归遍历)-(四补)

前面写了一些关于树的操作,但是没有实现树的遍历的非递归写法. 通常树有四种遍历方法:1.层次遍历(需要用到树的高度,此文没有考虑) 2.前序遍历(根左右):3.中序遍历(左根右):4.后序遍历(左右根) 树的结构如下: 层次遍历:123456789 前序遍历:124895367 中序遍历:849251637 后序遍历:894526731 java代码实现三种遍历的递归和和非递归实现 package com.lip.datastructure.tree; import java.util.Stac

并查集的 路径压缩(递归和非递归)

这里的思路是 在每一次的找父亲节点的时候我们把每一个孩子的父亲的改成他的祖先.因为有可能一个孩子的关系很复杂可能就是一条链,这样查找就没浪费时间. //这是简单的递归实现 find (int x) { while(x!=father[x]) father[x] = find(father[x]) ; return father[x] ; } //这是非递归的 find (int x) { int r = x ; while(r != father[r])//找到r的祖先节点 r = father

全排列算法的递归与非递归实现

全排列算法的递归与非递归实现 全排列算法是常见的算法,用于求一个序列的全排列,本文使用C语言分别用递归与非递归两种方法实现,可以接受元素各不相同的输入序列. 题目来自leetcode: Given a collection of numbers, return all possible permutations. For example, [1,2,3] have the following permutations: [1,2,3], [1,3,2], [2,1,3], [2,3,1], [3

递归转非递归(实例)

递归调用示例算法1.10  求取数组元素的最大值(递归算法)    procedure MAX1(i)    // 查找数组A中最大值元素,并返回该元素的最大下标.//        global integer n,A(1:n),j,k        integer i        if i<n then j←MAX1(i+1)  //递归调用//               if A(i) > A(j) then k←i                   else k←j       

数据结构——二叉树遍历之“递归与非递归遍历”

简述 二叉树的遍历分为先序遍历.中序遍历和后序遍历.如下图所示: 递归遍历 private void bianli1(List<Integer> list, TreeNode root) { // 先序遍历 if (root == null) { return; } list.add(root.val); bianli1(list, root.left); bianli1(list, root.right); } private void bianli2(List<Integer>

JAVA递归、非递归遍历二叉树(转)

原文链接: JAVA递归.非递归遍历二叉树 import java.util.Stack; import java.util.HashMap; public class BinTree { private char date; private BinTree lchild; private BinTree rchild; public BinTree(char c) { date = c; } // 先序遍历递归 public static void preOrder(BinTree t) {

Java数据结构系列之——树(4):二叉树的中序遍历的递归与非递归实现

package tree.binarytree; import java.util.Stack; /** * 二叉树的中序遍历:递归与非递归实现 * * @author wl * */ public class BiTreeInOrder { // 中序遍历的递归实现 public static void biTreeInOrderByRecursion(BiTreeNode root) { if (root == null) { return; } biTreeInOrderByRecursi