叶子结点

数据结构中涉及的排序算法

末鹿安然 提交于 2019-12-07 22:06:21
下面按照课本的分类,做了大致的内排序的归类的图片: 下面我们逐个来实现排序的算法: 一、插入排序算法: 包括:直接插入、折半插入、和希尔排序 其中,插入排序的思想都是一样的,都是以首个待排序的数字作为假设已经有序的序列,然后从已经有序的序列的最后一个位置,从后往前找满这趟比较中元素适合放置的位置。 1. 直接插入插入排序: /* 直接插入插入排序,假定首个元素有序, 待插入元素和前面的元素依次大小比较, 如果满足该元素小于前面一次由后到前的元素,就依次移动元素 循环判断 时间复杂度O(n^2) 稳定排序 基本有序时时间复杂度为O(n) */ void insertSort1(int a[], int n){ //直接插入排序 int temp,j; for(int i=1;i<n;i++){ temp = a[i]; j = i-1; while(j>=0 and temp<a[j]){ //逐个元素比较,逐个移动元素 a[j+1] = a[j]; j--; } a[j+1] = temp; } } void insertSort2(int a[], int n){ int i, j, temp; for(i=1;i<n;i++){ temp = a[i]; for(j=i-1;temp<a[j] and j>=0;j--){ a[j+1] = a[j]; } a[j+1] =

从数据结构分析mysql为何使用B+tree

大兔子大兔子 提交于 2019-12-06 16:41:19
理解mysql为何选择升级版的二叉树,就需要对各种常用的二叉树进行对比。B+Tree是一种特殊的二叉树,本质上也算二叉树。自然会满足二叉树的一般特性。 比如,比节点数据大的在右边,节点数据小的在左边。 二叉树(Binary Tree) :每个结点最多有两个子树的树结构。一棵深度为k,且有2^k-1个结点的二叉树,称为满二叉树。 AVL树(平衡二叉树) :它是一种排序的二叉树。主要特征:左右子树的树高差绝对值不能超过1. R-B Tree(Red/Black Tree)红黑树 ,本质上也是一种二叉树。  特性: 1)每个结点要么是红的,要么是黑的。 2)根结点是黑的。 3)每个叶结点(叶结点即指树尾端NIL指针或NULL结点)是黑的。 4)如果一个结点是红的,那么它的俩个儿子都是黑的。 5)对于任一结点而言,其到叶结点树尾端NIL指针的每一条路径都包含相同数目的黑结点。 * 新添加节点,均为红色。 B-Tree(B树) :是一种自平衡的树,能够保持数据有序。与二叉树的区别,可以有多个子节点,每个节点可以存储多个值。 m 阶(根结点中关键字的个数为1~m-1)的B树具有特性: 1)每个节点最多有 m 个子节点 2)除根节点和叶子节点,其它每个节点至少有 [m/2] (向上取整的意思)个子节点 3)若根节点不是叶子节点,则其至少有2个子节点 4)所有NULL节点到根节点的高度都一样 5

【转】各种二叉树

断了今生、忘了曾经 提交于 2019-12-06 16:05:22
数据库中的数据一般是放在磁盘里面,存取数据的时候就要访问磁盘, 物理访问过程:盘片旋转,磁臂移动 两个过程。盘片旋转到指定位置之后,移动磁臂开始进行数据的存取。 那么存取数据的时间(快慢)主要是在哪部分消耗呢?主要就是 定位 过程消耗的。 所以:考虑到提高存取数据的速率,实际上就是减少磁盘定位(I/O操作)的次数。 来举个例子。来 顺序查找 。 查找5的时候,从头到尾的遍历,一共需要定位5次。不用再赘述,显然这样的顺序查找是最低效的。 为了提高效率,来 二叉树 。 二叉树的规范我就不说了, 一共6个数,无论查找哪个数,最多也就定位3次。 嗯,既然二叉树这么方便,那大家都用二叉树好了。额,其实图一那种情况,也算是二叉树,那算是一种情况。如果无法保证提高效率的稳定性,那这种结构还是不好。 (在这里记录一个知识点) 先序,中序,后序遍历。说一点就好,这里的先中后,说的是根节点。 为了提升稳定性,来 平衡二叉树 。 平衡二叉树用平衡因子差值来判断是否平衡,并旋转二叉树。平衡因子:左右子树高度差。平衡二叉树里平衡因子不能超过1,否则旋转。 长叹一口气,这样稳定了吧? 稳定是稳定,但是为了二叉树的稳定,牺牲了一些更重要的东西——时间。 当新增删除数据导致的旋转二叉树时,很耗时间的! 所有的操作的目的都是为了节省时间,提高效率。这样操作舍本逐末了。但也不是丝毫没有可取之处。 使用场景

索引简记:B树 B+树

血红的双手。 提交于 2019-12-06 10:49:07
数据库索引演进: 1、二叉树 如上,二叉树当时算法中的鼻祖了,O(N)的复杂度也使得他应用声名大噪,hash即使脱胎于此 那么为什么hash索引很少使用呢?一是因为极端情况下二叉树会退化为一个链表失去其二叉树的优势 2、由此,B-树, 注意是B树不是B减数,就诞生了,B树可以简单理解为平衡M岔树。如下示例为3路B树 再附一张带指针的: B树:M个节点M+1个分叉,分为数据域和指针域,既存关键字,由存指针指向孩子节点,常用于文件系统索引。 B树是解决了退化的问题了,但是如上结构,在进行范围查询的时候,B树也是疲于奔命 3、由此,B+树诞生了,B+树是基于B树的拓展,示例如下: 再附一张带指针的 如此B+树就解决了范围查询的问题,且节点(空间)利用率也高过B树。常用于DB索引! B树与B+树的区别: 在B+树中,具有n个关键字的节点只含有n棵子树,即 每个关键字对应一个子树 ;而在B树中,具有n个关键字的节点只含有n+1棵子树。 在B+树中,每个结点(非根节点)关键字个数n的范围是m/2(向上取整)<=n<=m(根结点:1<=n<=m);在B树中,每个结点(非根节点)关键字个数n的范围是m/2(向上取整)-1<=n<=m-1(根结点:1<=n<=m-1)。 在B+树中, 叶结点包含信息,所有非叶子结点仅起到索引作用 ,非叶结点中的每个索引项只含有对应子树的 最大关键字

堆 堆排序 优先队列 图文详解(Golang实现)

ぐ巨炮叔叔 提交于 2019-12-06 08:25:20
引入 # 在实际应用中,我们经常需要从一组对象中查找 最大值 或 最小值 。当然我们可以每次都先排序,然后再进行查找,但是这种做法效率很低。哪么有没有一种特殊的数据结构,可以高效率的实现我们的需求呢,答案就是 堆(heap) 堆分为最小堆和最大堆,它们的性质相似,我们以最小堆为例子。 最小堆 # 举例 # 如上图所示,就为一个最小堆。 特性 # 是一棵完全二叉树 如果一颗二叉树的任何结点,或者是树叶,或者左右子树均非空,则这棵二叉树称做满二叉树(full binary tree) 如果一颗二叉树最多只有最下面的两层结点度数可以小于2,并且最下面一层的结点都集中在该层最左边的连续位置上,则此二叉树称做完全二叉树(complete binary tree) 局部有序 最小堆对应的完全二叉树中所有结点的值均不大于其左右子结点的值,且一个结点与其兄弟之间没有必然的联系 二叉搜索树中,左子 < 父 < 右子 存储结构 # 由于堆是一棵完全二叉树,所以我们可以用顺序结构来存储它,只需要计算简单的代数表达式,就能够非常方便的查找某个结点的父结点和子节点,既避免了使用指针来保持结构,又能高效的执行相应操作。 Copy 结点i的左子结点为2xi+1,右子结点为2xi+2 结点i的父节点为(i-1)/2 数据结构 # Copy // 本例为最小堆 // 最大堆只需要修改less函数即可 type

二叉树的基本概念

筅森魡賤 提交于 2019-12-06 08:05:45
二叉树的定义 一棵二叉树是结点的一个有限集合,该集合或者为空,或者是由一个根节点加上两棵分别称为左子树和右子树的、互不相交的二叉树组成。 二叉树的5种基本形态,任意一棵二叉树都由这5种形态组合而成 空二叉树,单节点二叉树,右子树为空的二叉树,左子树为空的二叉树,左右子树都有的二叉树 性质1 非空二叉树的第i层,最多有(2的(i-1)次方)个节点 性质2 高度为h的二叉树,最多有(2的h次方-1)个节点 性质3 对于任意一棵二叉树,如果它的叶子节点数为N0,度为2的节点数为N2,那么N0=N2+1 性质4 具有n个结点的完全二叉树的高度为log2(n+1)或log2(n)+1。 性质5 如果将一棵有n个结点的完全二叉树自顶向下,同一层自左向右连续给节点编号为1,2,3,···,n,然后按此结点编号将树中各结点顺序地存放于一个一位数组中,并简称编号为i的结点为结点i(1≤i≤n)。则有以下关系: 若i≤n/2,即2i≤n,则编号为i的结点为分支结点,否则为叶子结点。 若n为奇数,则每个分支结点都既有左孩子结点,也有右孩子结点;若n为偶数,则编号最大的分支结点(编号为n/2)只有左孩子节点,没有右孩子结点,其余分支结点都有左右孩子结点 若编号为i的结点有左孩子结点,则左孩子结点的编号为2i,若编号为i的结点有右孩子结点,则右孩子结点的编号为(2i+1)。 除根结点外,若一个结点的编号为i

数据结构树的专题

梦想的初衷 提交于 2019-12-06 06:57:39
一、二叉树的基本操作 #include<stdio.h> #include<stdlib.h> typedef char ElemType; typedef struct Node { ElemType data; struct Node *lchild, *rchild; } BiTree; BiTree *createBT() //键盘输入创建二叉树 { BiTree *b; ElemType ch; scanf("%c", &ch); fflush(stdin); // 清空键盘缓冲 if(ch != '#') // #表示空 { b = (BiTree *)malloc(sizeof(BiTree)); b->data = ch; printf("请输入%c的左孩子:", ch); b->lchild = createBT(); printf("请输入%c的右孩子:", ch); b->rchild = createBT(); } else b = NULL; return b; } void createBT(BiTree *&b, char *s) //用括号表示法的字符串s生成二叉树b { BiTree *st[100], *t; //st存放树结点的栈 int top = -1; int k; //k=1表示左孩子, k=2表示右孩子 b = NULL; while

44444

随声附和 提交于 2019-12-06 06:27:02
集合框架 一、Collection集合 集合:Java中提供的一种容器,用来存储多个数据。Collection是单列集合类的根接口。 集合和数组的区别:1.数组的长度是固定。集合的长度是可变的。2.数组中存储的是同一类型元素,可以存储基本数据类型值。集合存储的都是对象。而且对象的类型可以 不一致。 Collection常用功能 public boolean add(E e) : 把给定的对象添加到当前集合中 。public void clear() :清空集合中所有的元素。public boolean remove(E e) : 把给定的对象在当前集合中删除。public boolean contains(E e) : 判断当前集合中是否包含给定的对象。public boolean isEmpty() : 判断当前集合是否为空。public int size() : 返回集合中元素的个数。public Object[] toArray() : 把集合中的元素,存储到数组中。 Iterator迭代器 原理: 首先通过调用t集合的iterator()方法获得迭代器对象,然后使用hashNext()方法判断集合中是否存在下一个元素,如果存在,则调用next()方法将元素取出,否则说明已到达了集合末尾,停止遍历元素。 ​ Iterator迭代器对象在遍历集合时

八大排序算法

跟風遠走 提交于 2019-12-06 00:43:59
八大排序是《数据结构》这门大学计算机必修课中非常基础但是特别重要的知识点 常见的八大排序,他们之间关系如下: 一、直接插入排序(Insertion Sort) 直接插入排序的核心思想就是:将数组中的所有元素依次跟前面已经排好的元素相比较,如果选择的元素比已排序的元素小,则交换,直到全部元素都比较过 因此,从上面的描述中我们可以发现,直接插入排序可以用两个循环完成: 第一层循环:遍历待比较的所有数组元素 第二层循环:将本轮选择的元素(selected)与已经排好序的元素(ordered)相比较。 如果:selected > ordered,那么将二者交换。 算法代码: void print(int a[], int n ,int i){ cout<<i <<":"; for(int j= 0; j<8; j++){ cout<<a[j] <<" "; } cout<<endl; } void InsertSort(int a[], int n) { for(int i= 1; i<n; i++){ if(a[i] < a[i-1]){ //若第i个元素大于i-1元素,直接插入。小于的话,移动有序表后插入 int j= i-1; int x = a[i]; //复制为哨兵,即存储待排序元素 a[i] = a[i-1]; //先后移一个元素 while(x < a[j]){ /

堆 堆排序 优先队列 图文详解(Golang实现)

扶醉桌前 提交于 2019-12-05 22:17:04
引入 在实际应用中,我们经常需要从一组对象中查找 最大值 或 最小值 。当然我们可以每次都先排序,然后再进行查找,但是这种做法效率很低。哪么有没有一种特殊的数据结构,可以高效率的实现我们的需求呢,答案就是 堆(heap) 堆分为最小堆和最大堆,它们的性质相似,我们以最小堆为例子。 最小堆 举例 如上图所示,就为一个最小堆。 特性 是一棵完全二叉树 如果一颗二叉树的任何结点,或者是树叶,或者左右子树均非空,则这棵二叉树称做满二叉树(full binary tree) 如果一颗二叉树最多只有最下面的两层结点度数可以小于2,并且最下面一层的结点都集中在该层最左边的连续位置上,则此二叉树称做完全二叉树(complete binary tree) 局部有序 最小堆对应的完全二叉树中所有结点的值均不大于其左右子结点的值,且一个结点与其兄弟之间没有必然的联系 二叉搜索树中,左子 < 父 < 右子 存储结构 由于堆是一棵完全二叉树,所以我们可以用顺序结构来存储它,只需要计算简单的代数表达式,就能够非常方便的查找某个结点的父结点和子节点,既避免了使用指针来保持结构,又能高效的执行相应操作。 结点i的左子结点为2xi+1,右子结点为2xi+2 结点i的父节点为(i-1)/2 数据结构 // 本例为最小堆 // 最大堆只需要修改less函数即可 type Heap []int func (h Heap)