二分查找和顺序查找
- 格式:wps
- 大小:57.00 KB
- 文档页数:7
单片机常用算法设计详解一、排序算法排序是将一组数据按照特定的顺序进行排列的过程。
在单片机中,常见的排序算法有冒泡排序、插入排序和快速排序。
冒泡排序是一种简单直观的排序算法。
它通过反复比较相邻的两个元素,如果顺序不对则进行交换,直到整个数组有序。
这种算法的优点是实现简单,容易理解,但效率较低,对于大规模数据的排序不太适用。
插入排序的基本思想是将待排序的元素插入到已经有序的部分中。
它从第二个元素开始,将其与前面已排序的元素进行比较,并插入到合适的位置。
插入排序在小规模数据时表现较好,但其平均和最坏情况下的时间复杂度不如快速排序。
快速排序则是一种高效的排序算法。
它选择一个基准元素,将数组分为小于和大于基准元素的两部分,然后对这两部分分别进行快速排序。
快速排序在大多数情况下具有较好的性能,但在最坏情况下可能会退化为 O(n²)的时间复杂度。
在单片机中选择排序算法时,需要根据数据规模和对时间效率的要求进行权衡。
二、查找算法查找是在一组数据中寻找特定元素的过程。
常见的查找算法有顺序查找和二分查找。
顺序查找是从数组的开头依次比较每个元素,直到找到目标元素或遍历完整个数组。
它适用于数据无序的情况,但效率较低。
二分查找则要求数组必须是有序的。
通过不断将数组中间的元素与目标元素进行比较,缩小查找范围,直到找到目标元素。
二分查找的时间复杂度为 O(log n),效率较高,但需要数据有序。
在单片机应用中,如果数据经常需要查找且能保持有序,应优先考虑二分查找。
三、数据压缩算法在单片机系统中,为了节省存储空间和传输带宽,常常需要使用数据压缩算法。
常见的数据压缩算法有哈夫曼编码和 LZW 编码。
哈夫曼编码是一种无损数据压缩算法。
它根据字符出现的频率构建一棵哈夫曼树,然后为每个字符生成唯一的编码。
频率高的字符编码较短,频率低的字符编码较长,从而实现数据压缩。
LZW 编码则是一种字典编码算法。
它通过建立一个字典,将重复出现的字符串用较短的编码表示,从而达到压缩的目的。
常用算法解析及其应用场景算法是计算机科学中最基础的概念之一。
在日常生活中,我们无时无刻不在接触着各种算法,从谷歌搜索到智能手机里各种APP的推荐算法,都离不开算法的支持和应用。
在这篇文章中,我将为大家介绍常用的算法和它们的应用场景。
一、排序算法排序算法是程序中最常用的一种算法,其目的是将数据按一定方式进行排列。
常见的排序算法包括冒泡排序、选择排序、插入排序、归并排序和快速排序。
1、冒泡排序冒泡排序是一种简单的排序算法,它的思路是从头到尾扫描一遍需要排序的数据,每一次将相邻两个元素进行比较并交换位置。
这个过程类似于水泡在水中上浮,一遍扫描结束后,最大的元素就会像水泡一样浮到最上面。
冒泡排序的时间复杂度为O(n²),如果需要排序的数据量很大,那么执行起来会比较慢。
不过它的优点在于代码简单易懂,并且实现起来很容易。
2、选择排序选择排序的思路是每次从数据中选择一个最小(或最大)的元素,并将其放置在序列的起始位置。
按照这样的方式,每次只需要找到一个元素,就可以将数据序列排列好。
选择排序的时间复杂度也为O(n²),但它比冒泡排序要稍微快一点。
3、插入排序插入排序的思路是将数据分为已排序区间和未排序区间两部分。
不断地将未排序区间的元素逐一与已排序区间的元素相比较,找到合适的位置插入。
重复执行这个过程,最终就能将整个数据序列排列好。
插入排序的时间复杂度也为O(n²),但它的执行速度相对于冒泡排序和选择排序要慢一些。
不过它的优点在于它在处理小数据量时非常高效,并且在排序过程中需要的额外内存很少。
4、归并排序归并排序的思路是将数据分成两个子序列,分别进行排序,最后将排序好的子序列进行合并。
在合并的过程中,需要使用到一个额外的数组来存储数据。
归并排序的时间复杂度为O(nlogn),执行效率相对较高。
尤其是在处理大数据量时,它表现得十分出色。
5、快速排序快速排序的思路不同于以上几种排序算法,它是一种分治法的排序算法。
C语言常用算法程序汇总C语言是一门广泛应用于计算机编程的语言,具有较高的效率和灵活性。
在C语言中,常见的算法程序包括排序算法、查找算法、递归算法等等。
以下是一些常用的C语言算法程序的汇总:1.排序算法:-冒泡排序:通过多次迭代比较相邻元素并交换位置,将最大的元素逐渐移动到正确的位置。
-插入排序:将待排序的元素与已排序的部分依次比较并插入到正确的位置。
-选择排序:每次从待排序的元素中选择最小的元素并与已排序的部分交换位置。
-快速排序:通过选择一个基准元素,将数组划分为两个子数组进行递归排序。
2.查找算法:-顺序查找:逐个比较数组中的元素,直到找到目标元素或到数组末尾。
-二分查找:通过比较目标元素与数组中间元素的大小,逐步缩小范围,直到找到目标元素。
-哈希查找:通过散列函数将目标元素映射到哈希表的索引位置进行查找。
3.递归算法:-阶乘:通过递归调用自身计算一个正整数的阶乘。
-斐波那契数列:通过递归调用自身计算斐波那契数列的第n个数。
-二叉树遍历:通过递归调用自身遍历二叉树的各个节点。
4.图算法:- 最短路径算法:如Dijkstra算法和Floyd算法,用于计算图中两个节点之间的最短路径。
-拓扑排序:通过对有向无环图进行排序,使得所有的边从排在前面的节点指向排在后面的节点。
- 最小生成树:如Prim算法和Kruskal算法,用于找到图中连接所有节点的最小子树。
5.动态规划:-最长公共子序列:通过寻找两个字符串中的最长公共子序列,解决字符串匹配问题。
-背包问题:通过动态规划解决在给定容量下选取物品使得总价值最大的问题。
-最大子序列和:通过动态规划解决一个数组中选取连续子序列使得和最大的问题。
以上只是一些C语言中常用的算法程序的汇总,实际上,还有很多其他的算法,如逆波兰表达式、霍夫曼编码、最小割等等。
通过学习这些算法,可以更好地理解C语言的应用和开发。
⼆分查找与⼏种排序⽅法1. 递归⼆分查找2. 冒泡排序3. 选择排序4. 插⼊排序5. 归并排序6. 快速排序1、递归⼆分查找思想:使⽤⼆分查找的前提条件是数组元素必须已经排好序。
⼆分查找法⾸先将关键字与数组的中间元素进⾏⽐较,考虑下⾯三种情形:如果关键字⽐中间元素⼩,那么只需在前⼀半数组元素中进⾏递归查找;如果关键字与中间元素相等,则匹配成功,查找结束。
代码:public static int binarySearch(int[] list, int key){return binarySearch(list, key, 0, list.length - 1);}public static int binarySearch(int[] list, int key , int low, int high){//没有查找到if(low > high)return - low - 1;int mid = (low + high) / 2;if(key < list[mid]){return binarySearch(list, key, low, mid - 1);}else if(key == list[mid]){return mid;}else{return binarySearch(list, key, mid + 1, high);}}------------------------------------------------- 排序算法 ----------------------------------------------各排序算法的时间复杂度、空间复杂度、稳定性:(排序算法的稳定性:排序前后相等元素的相对位置不变,则称排序算法是稳定的;否则排序算法是不稳定的)排序算法平均时间复杂度最坏时间复杂度空间复杂度稳定性冒泡排序 O(n^2) O(n^2) O(1)稳定选择排序 O(n^2) O(n^2) O(1)不稳定直接插⼊排序 O(n^2) O(n^2) O(1)稳定归并排序 O(nlogn) O(nlogn) O(n)稳定快速排序 O(nlogn) O(n^2) O(logn)不稳定堆排序 O(nlogn) O(nlogn) O(1)不稳定冒泡排序: 冒泡排序算法需要多次遍历数组(N-1次),在每次遍历中,⽐较连续相邻的元素。
查找算法在实际应用中的选择与优化在当今数字化的时代,数据的处理和检索变得日益重要。
无论是在庞大的数据库中寻找特定的信息,还是在程序中快速定位所需的元素,查找算法都扮演着关键的角色。
正确选择和优化查找算法,可以显著提高系统的性能和效率,为用户带来更好的体验。
查找算法的种类繁多,常见的有顺序查找、二分查找、哈希查找等。
每种算法都有其特点和适用场景。
顺序查找是最为简单直观的一种查找算法。
它依次遍历数据集合中的每个元素,直到找到目标元素或者遍历完整个集合。
这种算法的优点是实现简单,对于小型、无序的数据集合或者数据集合的元素分布没有明显规律的情况,是一种可行的选择。
然而,其缺点也很明显,当数据量较大时,查找效率会非常低。
二分查找则是一种在有序数据集合中进行高效查找的算法。
它通过不断将数据集合对半分割,逐步缩小查找范围,从而快速定位目标元素。
二分查找的效率很高,时间复杂度为 O(log n)。
但它的前提是数据集合必须是有序的,如果数据集合经常动态变化,维护其有序性可能会带来较大的开销。
哈希查找则是通过将关键码映射到一个固定的哈希表中,从而实现快速查找。
哈希查找的平均时间复杂度可以达到 O(1),效率极高。
但哈希函数的设计至关重要,如果哈希函数设计不好,可能会导致大量的哈希冲突,从而影响查找效率。
在实际应用中,选择合适的查找算法需要综合考虑多个因素。
首先是数据量的大小。
如果数据量较小,顺序查找可能就足够了;而对于大规模的数据,二分查找或哈希查找可能更合适。
其次是数据的分布和有序性。
如果数据本身有序,二分查找会是很好的选择;如果数据无序且分布较为随机,哈希查找可能更能发挥优势。
此外,数据的动态变化情况也需要考虑。
如果数据经常插入、删除和修改,那么维护有序性可能会比较困难,此时哈希查找可能更适合。
而如果数据的更新操作相对较少,而查找操作频繁,那么可以在数据初始化时将其排序,然后使用二分查找。
除了选择合适的查找算法,对算法进行优化也是提高查找效率的重要手段。
数据结构中的查找算法总结静态查找是数据集合稳定不需要添加删除元素的查找包括:1. 顺序查找2. 折半查找3. Fibonacci4. 分块查找静态查找可以⽤线性表结构组织数据,这样可以使⽤顺序查找算法,再对关键字进⾏排序就可以使⽤折半查找或斐波那契查找等算法提⾼查找效率,平均查找长度:折半查找最⼩,分块次之,顺序查找最⼤。
顺序查找对有序⽆序表均适⽤,折半查找适⽤于有序表,分块查找要求表中元素是块与块之间的记录按关键字有序动态查找是数据集合需要添加删除元素的查找包括: 1. ⼆叉排序树 2. 平衡⼆叉树 3. 散列表 顺序查找适合于存储结构为顺序存储或链接存储的线性表。
顺序查找属于⽆序查找算法。
从数据结构线形表的⼀端开始,顺序扫描,依次将扫描到的结点关键字与给定值k相⽐较,若相等则表⽰查找成功 查找成功时的平均查找长度为: ASL = 1/n(1+2+3+…+n) = (n+1)/2 ; 顺序查找的时间复杂度为O(n)。
元素必须是有序的,如果是⽆序的则要先进⾏排序操作。
⼆分查找即折半查找,属于有序查找算法。
⽤给定值value与中间结点mid的关键字⽐较,若相等则查找成功;若不相等,再根据value 与该中间结点关键字的⽐较结果确定下⼀步查找的⼦表 将数组的查找过程绘制成⼀棵⼆叉树排序树,如果查找的关键字不是中间记录的话,折半查找等于是把静态有序查找表分成了两棵⼦树,即查找结果只需要找其中的⼀半数据记录即可,等于⼯作量少了⼀半,然后继续折半查找,效率⾼。
根据⼆叉树的性质,具有n个结点的完全⼆叉树的深度为[log2n]+1。
尽管折半查找判定⼆叉树并不是完全⼆叉树,但同样相同的推导可以得出,最坏情况是查找到关键字或查找失败的次数为[log2n]+1,最好的情况是1次。
时间复杂度为O(log2n); 折半计算mid的公式 mid = (low+high)/2;if(a[mid]==value)return mid;if(a[mid]>value)high = mid-1;if(a[mid]<value)low = mid+1; 折半查找判定数中的结点都是查找成功的情况,将每个结点的空指针指向⼀个实际上不存在的结点——外结点,所有外界点都是查找不成功的情况,如图所⽰。
上机实验报告实验课题:实现对有序数据集合的顺序查找和二分查找,并展示出查找过程设计思路:我们可以采用数组有序的保存所有数据,这样便于将数据的有序性和其索引的有序性统一起来,同时也便于查找数据。
需要声明的是,我们不使用零下标的项,这样做是为了在顺序查找中优化传统顺序查找算法,具体原因后面会有详细介绍。
为此,我们可以设计一个类,私有变量声明为该数组和数组的长度。
由于集合中的数据类型未知,所以该类为模板类。
对于公有成员,我们创建六个成员函数,除了构造函数和析构函数,其他四个函数分别用来获取外界传入的数组长度、获取外界传入的数组数据、对数据实现顺序查找、对数据实现二分查找。
这里,我们只重点介绍顺序查找函数和二分查找函数。
对于顺序查找,我们对传统的顺序查找方法进行优化,避开每次对数据索引是否越界进行判断这一步骤。
具体做法是:将所查找的元素保存在零下标的项中(这也是零下标闲置的原因),然后按照下标顺序从后向前依次遍历匹配所查找元素与数组元素。
若两者相等,展示出该数组元素,并将其下标值反馈给客户;若两者不相等,展示出该元素,进行下一轮匹配。
若最终标记下标达到零下标处,说明未查找到所要查找的元素,则客户反馈该信息。
优化后的顺序查找算法比传统的顺序查找算法减少一半的步骤,原因在于每次无须判断标记下标是否越界,这是该算法优化后的优点。
它的缺点是没有利用到数据集合有序这一性质,且查找效率低。
对于二分查找,我们声明三个整型变量low、high和mid 依次标记查找域的上界下标、下界下标和中值下标,其中mid=(low+high)/2。
我们在开始的时候将low初始化为1(上文中提到过,我们是从下表为1的位置开始存储数据),将high初始化为len(数组长度),并由此初始化mid的值。
对于任意一次查找,将索引为mid的值与所查找的值进行比较。
若两者相等,则将该元素的索引值反馈给客户;若所查找的值比索引为mid的值小,则将high的值变为mid-1,进行下一轮的查找;若所查找的值比索引为mid的值大,则将low 的值变为mid+1,进行下一轮查找。
若最终low>high,则表明未查找到所要查找的值,将此信息反馈给客户。
该算法是一种效率很高的算法,因为它充分利用到数据集合的有序性,这一优点在数据规模较大时体现的更明显。
实验过程分析:1.在编码过程中,出现了诸如语句末尾逗号遗漏等低级错误。
2.在对WL类的成员函数编码时,出现了函数声明错误,原因是对模板类的语法不熟,编码较少,对类面向对象这一思想理解不透彻。
3.在编码用户选择菜单等地方时,考虑到了程序的健壮性,添加了异常处理,比以前进步。
源代码:#include <iostream>#include "WL.h"#define MAX 10000 //定义数组的最大长度using namespace std;int main(){WL<int> p; //以整形数据为例,将模板类实例化int num,i,x; //num用来存储数组长度,x存储所查找的值int a[MAX];char s;cout<<"Please input the length of the array:"; //提示用户输入数组长度cin>>num;p.getlen(num);cout<<"Please input each data in order:"; //提示用户依次输入数据,并将其保存在数组中for(i=1;i<=num;i++)cin>>a[i];p.getdata(a,num);cout<<endl;cout<<"Please input the data searched:"; //提示用户输入所查找的值cin>>x;cout<<endl;loop:cout<<"Please choose the way for search:"<<endl; //提示用户选择查找方式,并进行查找cout<<"1. Order_search"<<endl;cout<<"2. Binary_search"<<endl<<endl;cout<<"Please input the figure notation:";cin>>s;cout<<endl;if(s=='1')p.find(x);else if(s=='2')p.binary_search(x);else{cout<<"Operator error!"<<endl<<endl; //若用户输入值不为‘1’或‘2’,对用户进行提示重新操作goto loop;}return 0;}***********************************************#ifndef WL_H_INCLUDED#define WL_H_INCLUDED#include <iostream>#define MAX 10000using namespace std;template <class T> //由于数据类型未知,采用模板类声明class WL{private:T s[MAX]; //对存储数据的数组进行声明int len; //对数组长度进行声明public:WL() {};~WL() {}void getlen(int num); //从外界获取数组长度值,并将其传给lenvoid getdata(T a[],int num); //从外界获取数组数据,并将其传给s[MAX] void find(const T x); //顺序查找函数声明void binary_search(const T x); //二分查找函数声明};template <class T>void WL<T>::getlen(int num){len=num;}template <class T>void WL<T>::getdata(T a[],int num){int i;for(i=1;i<=num;i++)s[i]=a[i];}template <class T>void WL<T>::find(const T x){int i=len; //将标记下标初始化为lens[0]=x; //将所查找元素赋给s[0]cout<<"The process of the search:";while(s[i]!=x) //若未查找到x,展示出该数据值{cout<<s[i]<<' ';i--;}if(i)cout<<s[i];cout<<endl;if(!i) //若i=0,说明查找失败,将该信息反馈给客户cout<<"Sorry,no result!"<<endl;else //若i!=0,将索引值反馈给客户cout<<"The index of the data is "<<i<<endl;}template <class T>void WL<T>::binary_search(const T x){int low=1,high=len; //声明并初始化low、highint mid;cout<<"The process of the search:";while(low<=high) //low<=high 说明还未找到所查找的值{mid=(low+high)/2;if(x==s[mid]) //若找到所查找的元素,将该值展示出来,并将索引值反馈给客户{cout<<s[mid]<<endl;cout<<"The index of the data is "<<mid<<endl;return;}else if(x<s[mid]) //若x比s[mid]小,将查找域上界变为mid-1{cout<<s[mid]<<' ';high=mid-1;}else //若x比s[mid]大,将查找域下界变为mid+1{cout<<s[mid]<<' ';low=mid+1;}}cout<<endl;cout<<"Sorry,no result!"<<endl; //若low>high,说明查找失败,将信息反馈给客户}#endif // WL_H_INCLUDED测试结果:顺序查找:二分查找:。