数据结构基础(2) --顺序查找 二分查找
顺序查找
适用范围:
没有进行排序的数据序列
缺点:
速度非常慢, 效率为O(N)
//实现
template <typename Type>
Type *sequenceSearch(Type *begin, Type *end, const Type &searchValue)
throw(std::range_error)
{if ((begin == end) || (begin == NULL) || (end == NULL))throw std::range_error("pointer unavailable");for (Type *index = begin; index < end; ++index){if (*index == searchValue)return index;}return end;
}template <typename Type>
Type *sequenceSearch(Type *array, int length, const Type &searchValue)
throw(std::range_error)
{return sequenceSearch(array, array+length, searchValue);
}
迭代二分查找
应用范围:
数据必须首先排序,才能应用二分查找;效率为(logN)
算法思想:
譬如数组{1, 2, 3, 4, 5, 6, 7, 8, 9},查找元素6,用二分查找的算法执行的话,其顺序为:
1.第一步查找中间元素,即5,由于5<6,则6必然在5之后的数组元素中,那么就在{6, 7, 8, 9}中查找,
2.寻找{6, 7, 8, 9}的中位数,为7,7>6,则6应该在7左边的数组元素中,那么只剩下6,即找到了。
二分查找算法就是不断将数组进行对半分割,每次拿中间元素和目标元素进行比较。
//实现:迭代二分
template <typename Type>
Type *binarySearch(Type *begin, Type *end, const Type &searchValue)
throw(std::range_error)
{if ((begin == end) || (begin == NULL) || (end == NULL))throw std::range_error("pointer unavailable");/**注意:此处high为end-1,并不是end因为在后续的查找过程中,可能会如下操作 (*high), 或等价的操作此时应该访问的是最后一个元素, 必须注意不能对数组进行越界访问!*/Type *low = begin, *high = end-1;while (low <= high){//计算中间元素Type *mid = low + (high-low)/2;//如果中间元素的值==要找的数值, 则直接返回if (*mid == searchValue)return mid;//如果要找的数比中间元素大, 则在数组的后半部分查找else if (searchValue > *mid)low = mid + 1;//如果要找的数比中间元素小, 则在数组的前半部分查找elsehigh = mid - 1;}return end;
}template <typename Type>
Type *binarySearch(Type *array, int length, const Type &searchValue)
throw(std::range_error)
{return binarySearch(array, array+length, searchValue);
}
递归简介
递归就是递归...(自己调用自己),递归的是神,迭代的是人;
递归与非递归的比较
//递归求解斐波那契数列
unsigned long ficonacciRecursion(int n)
{if (n == 1 || n == 2)return 1;elsereturn ficonacciRecursion(n-1) + ficonacciRecursion(n-2);
}
//非递归求解斐波那契数列
unsigned long ficonacciLoop(int n)
{if (n == 1 || n == 2)return 1;unsigned long first = 1, second = 1;unsigned long ans = first + second;for (int i = 3; i <= n; ++i){ans = first + second;first = second;second = ans;}return ans;
}
递归二分查找
算法思想如同迭代二分查找;
//实现
template <typename Type>
Type *binarySearchByRecursion(Type *front, Type *last, const Type &searchValue)
throw(std::range_error)
{if ((front == NULL) || (last == NULL))throw std::range_error("pointer unavailable");if (front <= last){Type *mid = front + (last-front)/2;if (*mid == searchValue)return mid;else if (searchValue > *mid)return binarySearchByRecursion(mid+1, last, searchValue);elsereturn binarySearchByRecursion(front, mid-1, searchValue);}return NULL;
}template <typename Type>
int binarySearchByRecursion(Type *array, int left, int right, const Type &searchValue)
throw (std::range_error)
{if (array == NULL)throw std::range_error("pointer unavailable");if (left <= right){int mid = left + (right-left)/2;if (array[mid] == searchValue)return mid;else if (searchValue < array[mid])return binarySearchByRecursion(array, left, mid-1, searchValue);elsereturn binarySearchByRecursion(array, mid+1, right, searchValue);}return -1;
}
小结:
其实C++ 的STL已经实现好了std::binary_search(),在用的时候我们只需调用即可, 但是二分算法的思想还是非常重要的, 在求解一些较为复杂的问题时, 我们时常能够看到二分的身影.
数据结构基础(2) --顺序查找 二分查找相关推荐
- 【Golang第6章:排序和查找】golang怎么排序,golang的顺序查找和二分查找,go语言中顺序查找二分查找介绍和案例
介绍 这个是在B站上看边看视频边做的笔记,这一章是GO语言的排序和查找 有golang怎么排序,golang的顺序查找和二分查找,go语言中顺序查找二分查找介绍和案例,具体请看[文章目录] 配套视频自 ...
- 数据结构与算法(8-2)有序表查找(折半查找(二分查找)、插值查找)
目录 一.折半查找(二分查找) 二.插值查找 总代码 一.折半查找(二分查找) 原理:一次次折半,不断向着查找值的位置靠近 . 适用场景:有序(必须) 流程:开始时,min标志首,max标志尾,med ...
- Python查找-二分查找
Python查找-二分查找 二分查找 折半查找法也称为二分查找法,它充分利用了元素间的次序关系,采用分治策略,可在最坏的情况下用O(log n)完成搜索任务. 它的基本思想是,将n个元素分成个数大致相 ...
- C语言之折半查找(二分查找)
一.什么是折半查找? 二分查找又称折半查找,优点是比较次数少,查找速度快,平均性能好:其缺点是要求待查表为有序表,且插入删除困难.因此,折半查找方法适用于不经常变动而查找频繁的有序列表.首先,假设表中 ...
- Java实现折半查找(二分查找)的递归和非递归算法
Java二分查找实现,欢迎大家提出交流意见. /** *名称:BinarySearch *功能:实现了折半查找(二分查找)的递归和非递归算法. *说明: * 1.要求所查找的数组已有序,并且其 ...
- php顺序、二分查找
$test_array = array (- 98, - 10, 0, 5, 6, 23, 98, 235 );$index1 = bin_sch ( $test_array, 0, 8, - 98 ...
- 顺序、二分查找文本数据
//顺序查找文本数据function seqSearch(arr,data) {for(var i=0;i<arr.length;i++){if(arr[i]==data){return i;} ...
- Java数据结构与算法——线性查找 二分查找 插值查找
1.线性查找 有一个数列: {1,8, 10, 89, 1000, 1234} ,判断数列中是否包含此名称[顺序查找] 要求: 如果找到了,就提示找到,并给出下标值. package com.szh. ...
- C语言基础02——控制语句。二分查找、随机数讲解、求自幂数、整数逆序、X图案打印、猜数字、公约数公倍数、素数
目录 分支语句(选择结构) if语句 switch语句 循环语句 while循环 do-while循环 for循环 循环语句的练习 转向语句 goto语句 break语句 continue语句 ret ...
最新文章
- TCP与UDP区别小结
- jsp:请求转发和重定向
- 机器学习实战笔记(Python实现)-01-机器学习实战
- 面向机器学习的特征工程翻译版
- PL/SQL编程基础(一):PL/SQL语法简介(匿名PL/SQL块)
- mysqladmin 设置用户名初始密码报错you need the SUPER privilege for this operation
- 互联网企业的电子商务社区会员模式浅谈
- 【Linux】统信UOS桌面壁纸右下角的统信UOS水印怎样去掉
- [PyTorch] 损失函数
- Echo团队Alpha冲刺随笔 - 第六天
- java逻辑运算符的使用
- hive like与rlike的区别
- 并发编程学习之Lock同步锁
- 零电压开关(ZVS)电路原理与设计(整理)
- C++if嵌套语句判断闰年
- 给游戏编个故事:《通关游戏设计之道》
- jupyter notebook 打开ipynb时提示到后台服务的连接没能建立, 我们会继续尝试重连, 请检出网络连接...还有服务配置 命令行显示Replacing stale connection
- 彭佳慧 - 走在红毯那一天
- 网上电子元器件采购商城:打破采购环节信息不对称难题,赋能企业高效协同管理
- protobuf c语言版本