查找算法

AVL树的插入、删除、查找操作

雨燕双飞 提交于 2019-11-29 21:16:36
AVL树 是一种带有平衡条件的二叉查找树,所有节点都是基于平衡的。所谓平衡,即某个节点的左右子树的高度差最多相差1。空树的高度定义为-1。 下面我们通过如下两棵树(图片来自《数据结构与算法分析–C语言描述》)进一步了解怎样的树才是AVL树。 上图只有左边的树才是AVL树,那么下面我们来分析一下左边的树 (某个节点的高 = MAX(子树的高, 右子树的高 )+ 1) 节点3的高为0 节点4的高为1 节点1的高为0 节点7的高为0 节点2的高为2 节点8的高为1 节点5的高为3 你可以看到任一节点的左右子树的差都没有超过2,那么我们再看看右边的树 节点2的高为2 节点8的高为0 所以对于节点7来说,左右子树的高度差相差为2 > 1,失去平衡。 下面我们接着来说AVL的插入、删除、查找操作。 插入和删除操作都有可能导致AVL树的不平衡 (为什么呢?原来的树是平衡的,即某个节点的左右子树的高度差小于2,假设左子树的高为1,右子树的高为0,如果这个时候,在这个节点的左子树插入一个节点,那么该节点的左右子树的高度差就为2了,删除操作也是一样的)。 对于出现不平衡的时候,需要通过 旋转 来解决。下面我们直接来看看插入操作。 插入操作 插入节点==》有可能失去平衡==》通过旋转操作来使树达到平衡 我们把需要重新平衡的节点叫做A,那么出现不平衡的情况,会有下面四种 : 1.

树内容理解之红黑树

梦想的初衷 提交于 2019-11-29 20:49:45
明白红黑树前需要理解的前提概念:   二叉查找树(BST)     1.左子树上所有节点的值均<=他的根节点的值     2.右子树上所有节点的值均>=他的根节点的值     3.左右子树也一定分别为二叉查找树 二叉查找树利用和二分查找相同的概念来进行数据的便捷查找:(二分查找见排序算法解释) 如果根节点足够大,二叉查找树“左腿”会很长。如下图: 此时为了平衡左腿节点,(最长路径不超过最短路径的两倍)引入平衡的二叉查找树=> 红黑树 : 红黑树满足:(在满足树自身是一个二叉查找树BST的前提下)   1.节点是红色或者黑色。   2.根节点是黑色。   3.每个叶子的节点都是黑色的空节点。   4.每个红色节点的两个子节点都是黑色的。   5.从任意节点到其每个叶子的所有路径都包含相同的黑色节点。 来源: https://www.cnblogs.com/saber123/p/11531581.html

线性表的定义和基本操作

妖精的绣舞 提交于 2019-11-29 19:29:57
线性表的定义 提到线性这个词,并不陌生,在 数据结构的基本概念 中学过线性的逻辑结构。线性逻辑结构是一对一关系,结点之间排成了一列或者一行,所以说 线性表也是一种逻辑关系 。有了对线性表的认知,那么来看一下它的概念: ​ 线性表 是具有 相同类型 的 n (n>=0) 个元素的 有限序列 ,其中 n 为表长,当 n=0 时,该表为空表。 为什么要相同类型?计算机在处理大量数据的时候,把相同的数据元素称作为数据对象。往往要处理相同的数据元素,也就处理一种数据对象。不会把音频和图片杂糅到一起进行处理。也不会把抽象事物,比如说人和汽车组合到一起进行处理。因为这样没有意义,也没有高的效率。 对于相同类型,在接下来所学到的所有的数据结构中都有这样的要求。因为具有相同类型的数据结构,它在解决实际问题,实现算法时,才更加的有意义。其次,对于这个类型的范围,它的定义其实并不狭隘,并不仅仅局限于我们常见的类型,比如说整型、浮点型这样的类型。对于从实际生活中抽象出来的类型,比如说一本书、一个人也是可以作为一个元素的。它与 C++ 中的面向对象的类比较相似。 除了相同类型,定义中还有一个比较重要的点,那就是是有限序列。什么是有限?就是说明该线性表的长度是有限的,因为计算机无法处理无限多的数据。第二个是序列,根据下面的表示方法可以发现,线性表中每一个元素都是有序号的,序列的意思就是有序号的一种排列

二叉搜索树

笑着哭i 提交于 2019-11-29 19:20:20
目录 一、什么是二叉搜索树 二、二叉搜索操作的特别函数: 三、二叉查找树的查找操作:Find 四、查找最大和最小元素 五、二叉搜索树的插入 六、二叉搜索树的删除 6.1 删除的是叶结点 6.2 删除的结点只有一个孩子结点 6.3 删除的结点有左右子树 七、Python递归实现-二叉搜索树 更新、更全的《数据结构与算法》的更新网站,更有python、go、人工智能教学等着你: https://www.cnblogs.com/nickchen121/p/11407287.html 一、什么是二叉搜索树 首先让我们回顾之前说过的 查找问题 :上次我们之讲过了静态查找,这次我们将通过二叉搜索树实现动态查找。但是针对动态查找,数据该如何组织呢? 二叉搜索树(BST,Binary Search Tree) ,也称 二叉排序树或二叉查找树 二叉搜索树:一颗二叉树,可以为空;如果不为空,满足以下性质: 非空 左子树 的所有 键值小于其根节点 的键值 非空 右子树 的所有 键值大于其根节点 的键值 左、右子树都是二叉搜索树 二、二叉搜索操作的特别函数: Position Find(ElementType X, BinTree BST):从二叉搜索树BST中查找元素X,返回其所在结点的地址; Postion FindMin(BinTree BST):从二叉搜索树BST中查找并返回最小元素所在结点的地址

二叉树的算法时间复杂度

你离开我真会死。 提交于 2019-11-29 18:51:13
二叉搜索树,平衡二叉树,红黑树的算法效率 操作 二叉查找树 平衡二叉树 红黑树 查找 O(n) O(logn) Olog(n) 插入 O(n) O(logn) Olog(n) 删除 O(n) O(logn) Olog(n) Olog(n)怎么算出来的 在一个树中查找一个数字, 第一次在根节点判断,第二次在第二层节点判断 以此类推,树的高度是多少就会判断多少次 树的高度和节点的关系就是以2为底,树的节点总数n的对数 来源: https://www.cnblogs.com/geektcp/p/11526925.html

C语言数组

泪湿孤枕 提交于 2019-11-29 18:46:29
引用: int a,b,c,d,...... int sum => 定义一类或一组变量 数组 1. 数组是什么? 数组是一组具有相同类型的数据(变量)的集合 C 语言中数组: 一维数组 二维数组 三维数组 ... 其实, C 语言中只有一维数组 2 ,一维数组 2.1 定义格式 类型说明符 数组名 [ 整型表达式 ] {={ 初始化列表 }}; {}: 可要可不要 " 类型说明符 ": 指定数组元素的类型,任意 C 语言合法的类型都可以 “ 数组名 ”:对象的名字,命名要符合 C 语言标识符的规定 “ 整型表达式 ” :指定数组中元素的个数,一般为常量表达式 eg: #define N 3 int a[10];// 定义了一个数组,数组名 a, 里面有 10 个 int 型元素 typeof(a) => 一个具有 10 个 int 元素的数组类型 int[10] char b[10]; typeof(b) => 一个具有 10 个 char 元素的数组类型 char[10] int c;// 在程序运行的时候,为 c 分配 4 个字节的空间 在程序运行的时候,为 a 分配多大的空间? 10 个 int = 》 40 个字节 sizeof(a) =>40 2.2 一维数组在内存中的存放 在连续的地址空间中,从 低地址到高地址依次存放 数组中的每个元素。 意思

LeetCode 5192. 查找集群内的「关键连接」

倾然丶 夕夏残阳落幕 提交于 2019-11-29 17:12:07
1. 问题 力扣数据中心有 n 台服务器,分别按从 0 到 n-1 的方式进行了编号。 它们之间以「服务器到服务器」点对点的形式相互连接组成了一个内部集群,其中连接 connections 是无向的。 从形式上讲, connections[i] = [a, b] 表示服务器 a 和 b 之间形成连接。任何服务器都可以直接或者间接地通过网络到达任何其他服务器。 「关键连接」是在该集群中的重要连接,也就是说,假如我们将它移除,便会导致某些服务器无法访问其他服务器。 请你以任意顺序返回该集群内的所有 「关键连接」。 示例 1: 输入:n = 4, connections = [[0,1],[1,2],[2,0],[1,3]] 输出:[[1,3]] 解释:[[3,1]] 也是正确的。 原题链接 ; 2. Tarjan算法 Tarjan 算法是在一个图中查找强连通分量的算法。强连通分量是指,每个顶点皆可由该图上的边抵达其他的每一个点的有向图。 算法的基本思想: 任选一个节点开始进行深度优先搜索(若深度优先搜索结束后仍有未访问的节点,则从中任选一点再次进行)。搜索过程中已访问的节点不再访问。 强连通分量的根: 指深度优先搜索是强连通分量重首个被访问的节点。 为找到根节点,我们给每个节点 v 一个深度优先搜索标号 v.index ,表示第几个被访问的节点。此外,每个节点有一个值 v

树、图、排序查找重要算法(960算法)

老子叫甜甜 提交于 2019-11-29 17:09:09
设计求T的WPL的算法:   (1) .给出二叉树结点的数据类型定义;   (2) .给出C语言描述算法;   【 1 】: typedef struct node { int weight; struct node *left,*right; //指向结点左右子女的指针 }BiNode,*BiTree;   【 2 】: int WPL=0; void inorder(BiTree bt,level lv) //bt是二叉树,lv是结点的层次,初值为1 { if(bt) {inorder (bt->left,lv+1); //中序遍历左子树 if(bt->left==null &&bt->right==null) //判断该结点是否为叶子 WPL+=(lv-1)*bt->weight; //累加结点带权路径长度 inorder(bt->right,lv+1); } } 【先序遍历】 NLR (递归) void PreOrder(BiTree T){ if(T!=NULL){ visit(T); //访问根结点 PreOrder(T->lchild); //递归遍历左子树 preOrder(T->rchild); } } 【中序遍历】 LNR (递归) void InOrder(BiTree T){ if(T!=NULL){ InOrder(T->lchild); visit(T)

算法学习笔记——查找问题

限于喜欢 提交于 2019-11-29 16:36:46
学习笔记,仅做记录。 1.顺序查找 使用方法:蛮力法 平均时间复杂度为O(n) package com.viper.search; public class SeqSearch { public static int getIndex ( int searchKey, int [] array) { for ( int i = 0 ; i < array.length; i++) { if (searchKey == array[i]) return i; } return - 1 ; } /** * (改进)设置哨兵,减少循环判断 */ public static int getIndexImprove ( int searchKey, int [] array) { int index = array.length; // 高端开始遍历 if (array[ 0 ] == searchKey) { return 0 ; } array[ 0 ] = searchKey; // 设置哨兵,防止越界 while (array[index] != searchKey) { index--; } return index == 0 ? - 1 : index; } } 2.折半查找 / 二分查找 使用方法:减治法 使用条件:元素有序 平均时间复杂度为 O ( log 2 n ) //-

学习笔记——查找

好久不见. 提交于 2019-11-29 16:36:33
目录 顺序查找 折半查找 二叉排序树 散列表 顺序查找 算法思想不必赘述。 ASL成功=Σ(i=1~n)pi*ci,其中ci是查找到元素i需要进行比较的次数,pi一般取1/n。 ASL不成功=n,即遍历所有元素都没有找到目标关键字,有的序列会增加一个元素用来判断是否达到尾部或者防止溢出,这时候ASL不成功=n+1 折半查找 int Bsearch(int a[],int low,int high,int mid) { int mid; while(left<=right) { mid=(left+right)/2; if(a[mid]==key) return mid; else if(a[mid]<k) left=mid+1; else right=mid-1; } return 0; } ASL成功=Σ目标关键词在判定树中的层数/数组长度 ASL不成功=Σ(叶子节点层数+1)/空指针数 二叉排序树 定义:若左子树不为空,则左子树上的节点都小于根节点的关键字;若右子树不为空,则右子树上的节点都大于根节点的关键字。 /*查找关键字的算法*/ BTNode BSTSearch(BTNode* bt,int key) { if(bt==NULL) return NULL; else { if(bt->data==key) return bt; else if(bt->data<key)