经典查找算法

1.顺序查找法

从序列的一端到另一端,找到元素返回对应下标,退出循环。
可能找的到,也可能找不到。
时间复杂度O(n)

int find(vector <int>nums, int target)
{for(int i=0; i<nums.size(); i++){if(nums[i]==target) return i;
}return NULL;
}

2.哨兵法查找

选取头部(尾部)位置做哨兵,从尾部(头部)开始便利到头部(尾部),找到对应元素则返回下标。
原来的内存中有一个单元是不用的,这个单元用来存储哨兵。一定会找到,因为有哨兵。

// 0 号位置不放原始数据,用来存储哨兵(待查找的数据) 
int find(vector <int>nums, int target)
{arr[0] = target;for(int i=nums.szie()-1; i>0; i--){if(nums[i]==target) return i;
}return NULL;
}

3.二分查找

前提:序列有序,并且顺序存取。因此链表不能跳着访问。
每一次都是拿要查找的数和子序列的中间位置比较,如果要查找的数比中间位置的小就往左边找,反之向右边找,如果找到返回中间位置下边,精力多次找不到返回-1.

int binarySearch(vector <int> nums, int left, int right)
{int left = 0, right = length - 1, mid;while(left<=right){mid = left + (right - left)/2;if(key < arr[mid]) left = mid+1;else if(key == arr[mid]) return mid;else right = mid-1;
}
}

4.分块查找

O(logK+m)

typedef struct Data{int key;int index;
}Data, ST;int blocksearch(int arr[], int length, ST* st, int len_st, int key)
{int left = 0. right = len_st -1;int mid = left + ((right - left) >> 1);while(left < right){if(key < st[mid].key) right = mid; // 因为包含最大值在其中,所以不能漏掉right 所对应的值else if(key > st[mid].key) left = mid + 1; // 因为left 所有对应的比过了,就直接跳开else break;mid =  left + ((right - left) >> 1);
}int begin = st[mid].index;int end = mid >= len_st - 1? length :st[mid+1].index;while (begin < end){if(key==arr[begin]) return begin;begin++;
}return -1;
}

二叉查找树

左节点小于父节点,右节点大于父节点。 链式存储,适合插入和删除。


bool search(Node* root, int key)
{while (root != NULL){if (key == root->data)return true;else if (key < root->data)root = root->left;elseroot = root->right;}return false;
}

平衡二叉树

AVL树又称为平衡二叉树,即Balanced Binary Tree或者Height-Balanced Tree,它或者是一棵空二叉树,或者是具有如下性质的二叉查找树:
左子树和右子树都是高度平衡的二叉树;
左子树和右子树的高度之差的绝对值不超过1。

#include <stdio.h>
#include <stdlib.h>//分别定义平衡因子数
#define LH +1
#define EH  0
#define RH -1typedef int ElemType;
typedef enum {false,true} bool;//定义二叉排序树
typedef struct BSTNode{ElemType data;	//节点存储的数据int bf;	//平衡标志struct BSTNode *lchild,*rchild;
}*BSTree,BSTNode;//对以 p 为根结点(以 p 为轴)的二叉树做右旋处理,令 p 指针指向新的树根结点
void R_Rotate(BSTree* p)
{// 令 p 的左孩子的右孩子作为 p 的左孩子BSTree lc = (*p)->lchild;(*p)->lchild = lc->rchild;//令 p 作为 p 的左孩子的右孩子lc->rchild = *p;// 令 p 的左孩子作为新的根节点*p = lc;
}//对以 p 为根结点(以 p 为轴)的二叉树做左旋处理,令 p 指针指向新的树根结点
void L_Rotate(BSTree* p)
{// 令 p 的右孩子的左孩子作为 p 的右孩子BSTree rc = (*p)->rchild;(*p)->rchild = rc->lchild;//令 p 作为 p 的右孩子的左孩子rc->lchild = *p;// 令 p 的右孩子作为新的根节点*p = rc;
}//对以指针 T 所指向结点为根结点的二叉树作左子树的平衡处理,令指针 T 指向新的根结点
void LeftBalance(BSTree* T)
{BSTree lc,rd;lc = (*T)->lchild;//进入此方法前就已经判断为左旋了,还需要确定是哪种左旋:1、直接左旋,2、先左旋后右旋//查看以 T 的左子树为根结点的子树,失去平衡的原因://  如果 bf 值为 1 ,则说明添加在左子树为根结点的左子树中,需要对其进行右旋处理;//  反之,如果 bf 值为 -1,说明添加在以左子树为根结点的右子树中,需要进行双向先左旋后右旋的处理switch (lc->bf){case LH:(*T)->bf = lc->bf = EH;R_Rotate(T);break;case RH:rd = lc->rchild;switch(rd->bf)	//这部分不好理解,拿笔在纸上画一画就特别好理解了(这部分的情况在前面的讲解里没有){case LH:(*T)->bf = RH;lc->bf = EH;break;case EH:(*T)->bf = lc->bf = EH;break;case RH:(*T)->bf = EH;lc->bf = LH;break;}rd->bf = EH;L_Rotate(&(*T)->lchild);R_Rotate(T);break;}
}
//右子树的平衡处理同左子树的平衡处理完全类似
void RightBalance(BSTree* T)
{BSTree lc,rd;lc= (*T)->rchild;switch (lc->bf){case RH:(*T)->bf = lc->bf = EH;L_Rotate(T);break;case LH:rd = lc->lchild;switch(rd->bf){case LH:(*T)->bf = EH;lc->bf = RH;break;case EH:(*T)->bf = lc->bf = EH;break;case RH:(*T)->bf = EH;lc->bf = LH;break;}rd->bf = EH;R_Rotate(&(*T)->rchild);L_Rotate(T);break;}
}//taller 用于记录插入新节点后是否使相应的子树高度增加,从而根据平衡因子判断是否需要対树进行平衡
//算法使用了递归,插入完成后,逐层向上对相应子树进行处理
//无返回值的地方,统一在最后 return 1;
int InsertAVL(BSTree* T,ElemType e,bool* taller)
{//如果本身为空树(树的根节点或相应子树为空),则直接添加 e 为根结点if ((*T)==NULL){(*T)=(BSTree)malloc(sizeof(BSTNode));(*T)->bf = EH;(*T)->data = e;(*T)->lchild = NULL;(*T)->rchild = NULL;*taller=true;}//如果二叉排序树中已经存在 e ,则不做任何处理else if (e == (*T)->data){*taller = false;return 0;}//如果 e 小于结点 T 的数据域,则插入到 T 的左子树中else if (e < (*T)->data){//如果插入过程,不会影响树本身的平衡,则直接结束if(!InsertAVL(&(*T)->lchild,e,taller))return 0;//判断插入过程是否会导致整棵树的深度 +1if(*taller){//判断根结点 T 的平衡因子是多少,由于是在其左子树添加新结点的过程中导致失去平衡,//所以当 T 结点的平衡因子本身为 1(左高)时,需要进行左子树的平衡处理,否则更新树中各结点的平衡因子数switch ((*T)->bf){case LH:LeftBalance(T);	// 左旋対树进行平衡,平衡后树的高度不会增加*taller = false;break;case EH:(*T)->bf = LH;	//更新平衡因子*taller = true;break;case RH:(*T)->bf = EH;	//更新平衡因子*taller = false;break;}}}//同样,当 e>T->data 时,需要插入到以 T 为根结点的树的右子树中,同样需要做和以上同样的操作else{if(!InsertAVL(&(*T)->rchild,e,taller))return 0;if (*taller){switch ((*T)->bf){case LH:(*T)->bf = EH;*taller = false;break;case EH:(*T)->bf = RH;*taller = true;break;case RH:RightBalance(T);*taller = false;break;}}}return 1;
}//判断现有平衡二叉树中是否已经具有数据域为 e 的结点
bool FindNode(BSTree root,ElemType e,BSTree* pos)
{BSTree pt = root;(*pos) = NULL;while(pt){if (pt->data == e){//找到节点,pos指向该节点并返回true(*pos) = pt;return true;}else if (pt->data>e){pt = pt->lchild;}elsept = pt->rchild;}return false;
}//中序遍历平衡二叉树
void InorderTra(BSTree root)
{if(root->lchild)InorderTra(root->lchild);printf("%d ",root->data);if(root->rchild)InorderTra(root->rchild);
}int main()
{int i,nArr[] = {1,23,45,34,98,9,4,35,23};BSTree root=NULL,pos;bool taller;//用 nArr查找表构建平衡二叉树(不断插入数据的过程)for (i=0;i<9;i++){InsertAVL(&root,nArr[i],&taller);}//中序遍历输出InorderTra(root);//判断平衡二叉树中是否含有数据域为 103 的数据if(FindNode(root,103,&pos))printf("\n%d\n",pos->data);elseprintf("\nNot find this Node\n");return 0;
}

哈希表查找


本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/bicheng/11908.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Web APIs(获取元素+操作元素+节点操作)

目录 1.API 和 Web API 2.DOM导读 DOM树 3.获取元素 getElementById获取元素 getElementsByTagName获取元素 H5新增方法获取 获取特殊元素 4.事件基础 执行事件 操作元素 修改表单属性 修改样式属性 使用className修改样式属性 获取属性的值 设置属性的值 移除…

Git系列:git show 使用技巧

&#x1f49d;&#x1f49d;&#x1f49d;欢迎莅临我的博客&#xff0c;很高兴能够在这里和您见面&#xff01;希望您在这里可以感受到一份轻松愉快的氛围&#xff0c;不仅可以获得有趣的内容和知识&#xff0c;也可以畅所欲言、分享您的想法和见解。 推荐:「stormsha的主页」…

Visual Studio使用——vs解决方案显示所有文件

目录 引出vs解决方案显示所有文件Idea安装和使用0.Java下载 和 IDEA工具1.首次新建项目2.隐藏文件不必要显示文件3.目录层级设置4.Settings设置选择idea的场景提示代码不区分大小写 取消git的代码作者显示 总结 引出 Visual Studio使用——自定义代码片段 & 像使用IDEA一样…

台式电脑屏幕亮度怎么调节?让你的眼睛更舒适!

在日常使用台式电脑时&#xff0c;调节屏幕亮度是一项常见的需求。不同的环境和个人偏好可能需要不同的亮度设置。因此&#xff0c;了解台式电脑屏幕亮度怎么调节是非常重要的。本文将介绍三种常见的方法&#xff0c;帮助您轻松调节台式电脑屏幕亮度&#xff0c;以满足您的需求…

asp.net core mvc razor动态编译

开发mvc过程中razor页面需要重启才能编译&#xff0c;非常麻烦&#xff0c;能否实现动态编译&#xff0c;微软官方提供了一个包能实现 新建.net 6 mvc项目 安装Microsoft.AspNetCore.Mvc.Razor.RuntimeCompilation 修改csproj <Project Sdk"Microsoft.NET.Sdk.Web…

目标检测——YOLOv9算法解读

论文&#xff1a;YOLOv9: Learning What You Want to Learn Using Programmable Gradient Information (2024.2.21) 作者&#xff1a;Chien-Yao Wang, I-Hau Yeh, Hong-Yuan Mark Liao 链接&#xff1a;https://arxiv.org/abs/2402.13616 代码&#xff1a;https://github.com/W…

【微信小程序开发】深入探索事件绑定、事件冒泡、页面跳转的逻辑实现

✨✨ 欢迎大家来到景天科技苑✨✨ &#x1f388;&#x1f388; 养成好习惯&#xff0c;先赞后看哦~&#x1f388;&#x1f388; &#x1f3c6; 作者简介&#xff1a;景天科技苑 &#x1f3c6;《头衔》&#xff1a;大厂架构师&#xff0c;华为云开发者社区专家博主&#xff0c;…

每日一题11:Pandas:数据重塑-透视

一、每日一题 解答&#xff1a; import pandas as pddef pivotTable(weather: pd.DataFrame) -> pd.DataFrame:df_pivot weather.pivot(indexmonth, columnscity, valuestemperature)return df_pivot 题源&#xff1a;力扣 二、总结 Pandas 是一个强大的 Python 数据分析…

数据可视化(十):Pandas数据分析师职位信息表分析——箱线图、水平柱状图、学历城市双维分析等高级操作

Tips&#xff1a;"分享是快乐的源泉&#x1f4a7;&#xff0c;在我的博客里&#xff0c;不仅有知识的海洋&#x1f30a;&#xff0c;还有满满的正能量加持&#x1f4aa;&#xff0c;快来和我一起分享这份快乐吧&#x1f60a;&#xff01; 喜欢我的博客的话&#xff0c;记得…

20240513每日后端---聊聊策略模式+责任链解决业务多if判断

责任链模式 责任链模式是一种行为设计模式&#xff0c; 允许你将请求沿着处理者链进行发送。 收到请求后&#xff0c; 每个处理者均可对请求进行处理&#xff0c; 或将其传递给链上的下个处理者。 策略模式 策略模式是一种行为设计模式&#xff0c; 它能让你定义一系列算法&…

Rpcx (二):传输

一、Transport 传输 rpcx 可以通过 TCP、HTTP、UnixDomain、QUIC和KCP通信。你也可以使用http客户端通过网关或者http调用来访问rpcx服务。 TCP 这是最常用的通信方式。高性能易上手。可以使用TLS加密TCP流量。 Example: 101basic 服务端使用 tcp 做为网络名并且在注册中心…

C++之map和set 的封装

通过红黑树的学习&#xff08;C之红黑树-CSDN博客&#xff09;让我了解到map和set的底层如何实现&#xff0c;这一次我们来对map和set进行封装。 目录 1.map和set底层原理 2.map和set的定义 3.map和set的仿函数 4.map和set的插入 5.map和set的迭代器 5.1迭代器的构造 5.2…

Maven修改本地仓库的默认路径

前言 忽然发现当时下载Maven时候的默认路径没有与Maven放到同一个文件夹内&#xff0c;强迫症的我就想着修改一下Maven的路径&#xff01;也方便后续我的jar包管理&#xff0c;放到C盘下可能会导致占用C盘空间等等问题吧。以下是我的操作过程&#xff1a; 一、创建一个本地仓库…

QX---mini51单片机学习---(6)独立键盘

目录 1键盘简绍 2按键的工作原理 3键盘类型 4独立键盘与矩阵键盘的特点 5本节相关原理图 6按键特性 7实践 1键盘简绍 2按键的工作原理 内部使用轻触按键&#xff0c;常态按下按键触点才闭合 3键盘类型 编码键盘与非编码键盘 4独立键盘与矩阵键盘的特点 5本节相关原理…

GStreamer中如何自定义配置线程优先级

1.引言 如果看了gstreamer官方教程配置多线程出现编译不过的问题了&#xff0c;不妨进来看看这篇文章或许能解决一些编译问题。 GStreamer 本质上是多线程的&#xff0c;并且是完全线程安全的。大多数线程内部对应用程序是隐藏的&#xff0c;这应该使应用程序开发更容易。但是&…

RabbitMQ--死信队列

目录 一、死信队列介绍 1.死信 2.死信的来源 2.1 TTL 2.2 死信的来源 3.死信队列 4.死信队列的用途 二、死信队列的实现 1.导入依赖 pom.xml 2.application.properties 3.配置类 4.生产者 5.业务消费者&#xff08;正常消费者&#xff09; 6.死信队列消费者 一、…

Linux系统安全整改实践指南

在当前信息化高速发展的时代&#xff0c;Linux操作系统凭借其开源、稳定和高效的特点&#xff0c;在服务器市场占据着举足轻重的地位。然而&#xff0c;随着网络威胁的日益复杂化&#xff0c;确保Linux系统的安全性成为了一项至关重要的任务。本文旨在提供一套全面的Linux系统安…

leetcode 1319.连通网络的操作次数

思路&#xff1a;DFS&#xff08;连通块&#xff09; 其实一开始的时候&#xff0c;并不知道这道题的精髓在哪&#xff0c;总想着&#xff0c;啊&#xff1f;这怎么用图论的思想做啊&#xff1f; 细细思考之后&#xff0c;这道题还是比较有意思的&#xff0c;需要有一定的数据…

# Mysql 数据库区分大小写吗?

Mysql 数据库区分大小写吗&#xff1f; 1、MySQL 数据库在区分大小写方面有特定的行为&#xff0c;这取决于多个因素&#xff0c;包括操作系统、配置参数以及使用的字符集。 2、数据库名和表名&#xff1a; 在 Linux 系统中&#xff0c;数据库和表名是严格区分大小写的。 而…

【前端性能优化】深入解析重绘和回流,构建高性能Web界面

&#x1f525; 个人主页&#xff1a;空白诗 文章目录 &#x1f3af; 引言&#xff1a;探索Web性能的基石&#x1f3d7;️ 基础概念&#xff1a;什么是重绘和回流&#xff1f;&#x1f4cc; 回流&#xff08;Reflow&#xff09;&#x1f4cc; 重绘&#xff08;Repaint&#xff0…