
数据结构
数据结构
qnbk
这个作者很懒,什么都没留下…
展开
-
数据结构--跳表
跳表原创 2022-09-27 09:49:29 · 359 阅读 · 1 评论 -
数据结构 图
图原创 2022-05-27 16:00:15 · 588 阅读 · 3 评论 -
数据结构 B-树
B-树B-树B-数的插入实现B-树的插入B+树和B*树B+树B*树总结B-树的应用索引B-树1970年,R.Bayer和E.mccreight提出了一种适合外查找的树,它是一种平衡的多叉树,称为B树(有些地方写 的是B-树,注意不要误读成"B减树")。一棵M阶(M>2)的B树,是一棵平衡的M路平衡搜索树,可以是空树或 者满足一下性质:根节点至少有两个孩子每个非根节点至少有M/2(上取整)个孩子,至多有M个孩子每个非根节点至少有M/2-1(上取整)个关键字,至多有M-1个关键字,并且以原创 2022-05-27 11:59:22 · 755 阅读 · 1 评论 -
LRU Cache
LRU CacheLRU Cache的实现LRU是Least Recently Used的缩写,意思是最近最少使用,它是一种Cache替换算法。Cache:狭义的Cache指的是位于CPU和主存间的快速RAM, 通常它不像系统主存那样使用DRAM技术,而使用昂贵但较快速的SRAM技术。 广义上的Cache指的是位于速度相差较大的两种硬件之间, 用于协调两者数据传输速度差异的结构。除了CPU与主存之间有Cache, 内存与硬盘之间也有Cache,乃至在硬盘与网络之间也有某种意义上的Cache── 称为I原创 2022-05-26 19:44:28 · 939 阅读 · 0 评论 -
数据结构--并查集
并查集并查集原理并查集实现并查集原理在一些应用问题中,需要将n个不同的元素划分成一些不相交的集合。开始时,每个元素自成一个单元素集合,然后按一定的规律将归于同一组元素的集合合并。在此过程中要反复用到查询某一个元素归属于那个集合的运算。适合于描述这类问题的抽象数据类型称为并查集(union-find set)。并查集是一个森林–多棵树构成并查集由多个集合构成,每个集合都可以认为是一棵树并:合并多个集合查:两个值是否在一个集合举例:某学校招生10人,数学类招4人,英语类招3人,语文类招3人,原创 2022-05-27 08:30:00 · 238 阅读 · 0 评论 -
剑指 Offer II 116省份数量
省份数量题目描述:解题方法:并查集class UnionFindSet{public: UnionFindSet(size_t n) { _ufs.resize(n, -1); } void Union(int x1, int x2)//x1和x2所在集合的合并 { assert(x1 < _ufs.size()); assert(x2 < _ufs.size()); int root1 = FindRoot(x1); int root2 = Find原创 2022-05-26 18:22:07 · 236 阅读 · 0 评论 -
C++ 哈希
原创 2022-02-04 11:20:20 · 1113 阅读 · 0 评论 -
C++ 红黑树
红黑树原创 2022-01-28 19:00:27 · 1645 阅读 · 0 评论 -
C++ AVL树
AVL树底层结构AVL树(高度平衡搜索二叉树)AVL树的插入四种旋转右单旋左单旋右左双旋左右双旋AVL实现代码AVL树的性能底层结构map/set/multimap/multiset等这些容器其底层都是按照二叉搜索树来实现的但是二叉搜索树有其自身的缺陷,eg:往树中插入的元素有序或接近有序,二叉搜索树就会退化成单支树,时间复杂度会退化成O(N),因此map,set等关联式容器的底层结构是对二叉树进行了平衡处理,即采用平衡树来来实现。AVL树(高度平衡搜索二叉树)二叉搜索树虽然可以缩短查找的效率,但如原创 2022-01-27 14:11:43 · 1352 阅读 · 0 评论 -
C++二叉树进阶
二叉树进阶二叉搜索树二叉搜索树概念二级目录三级目录二叉搜索树二叉搜索树概念二叉搜索树又称二叉排序树,它或者是一棵空树,或者是具有以下性质的二叉树:若它的左子树不为空,则左子树上所有节点的值都小于根节点的值若它的右子树不为空,则右子树上所有节点的值都大于根节点的值它的左右子树也分别为二叉搜索树时间复杂度:O(N),只有当树的形状接近完全二叉树或者满二叉树,才能达到 logN搜索二叉树延伸:AVLTree 红黑树(对搜索二叉树左右高度提出要求,非常接近完全二叉树,效率可达到 O(logN))原创 2021-10-24 08:58:55 · 2446 阅读 · 0 评论 -
排序
排序直接插入排序希尔排序选择排序直接插入排序void InsertSort(int* a, int n){ //多趟排序 for (int i = 0; i < n - 1; ++i) { int end = i; //把tmp插入到数组的[0,end]有序区间中 int tmp = a[end + 1]; while (end >= 0) { if (tmp < a[end]) { a[end + 1] = a[end]; e原创 2021-05-10 16:12:30 · 204 阅读 · 8 评论 -
牛客---二叉树遍历
二叉树遍历题目描述:编一个程序,读入用户输入的一串先序遍历字符串,根据此字符串建立一个二叉树(以指针方式存储)。 例如如下的先序遍历字符串: ABC##DE#G##F### 其中“#”表示的是空格,空格字符代表空树。建立起此二叉树以后,再对二叉树进行中序遍历,输出遍历结果。题目来源:牛客#include <stdio.h>#include <stdlib.h>typedef struct TreeNode{ struct TreeNode* left;原创 2021-05-07 19:57:32 · 196 阅读 · 1 评论 -
平衡二叉树
平衡二叉树题目描述:给定一个二叉树,判断它是否是高度平衡的二叉树。本题中,一棵高度平衡二叉树定义为:一个二叉树每个节点 左右两个子树的高度差的绝对值不超过 1题目来源:leetcode思路:每个子树的左右子树比较nt maxDepth(struct TreeNode* root){ if(root == NULL) return 0; return fmax(maxDepth(root->left),maxDepth(root->right))+原创 2021-05-07 19:32:09 · 125 阅读 · 1 评论 -
另一个树的子树
另一个树的子树题目描述:给定两个非空二叉树 s 和 t,检验 s 中是否包含和 t 具有相同结构和节点值的子树。s 的一个子树包括 s 的一个节点和这个节点的所有子孙。s 也可以看做它自身的一棵子树。题目来源:力扣(LeetCode)思路:若t是s的子树t与s的所有子树都比较一遍,有相等即可bool isSameTree(struct TreeNode* p,struct TreeNode* q){ if(p == NULL && q == NULL)原创 2021-05-07 18:47:52 · 92 阅读 · 1 评论 -
对称二叉树
判断是否为对称二叉树题目描述:给定一个二叉树,检查它是否是镜像对称的。例如,二叉树 [1,2,2,3,4,4,3] 是对称的。但是下面这个 [1,2,2,null,3,null,3] 则不是镜像对称的:题目来源:力扣(LeetCode)思路:左子树跟右子树比较;左子树的左子树跟右子树的右子树比较;左子树的右子树跟右子树的左子树比较bool _isSymmetric(struct TreeNode* left,struct TreeNode* right){ if(left =原创 2021-05-07 18:18:34 · 97 阅读 · 1 评论 -
判断两棵树是否相同
判断两棵树是否相同题目要求:给你两棵二叉树的根节点 p 和 q ,编写一个函数来检验这两棵树是否相同。如果两个树在结构上相同,并且节点具有相同的值,则认为它们是相同的。(题目来源:力扣)bool isSameTree(struct TreeNode* p, struct TreeNode* q){ if(p == NULL && q == NULL) return true; if(p == NULL|| q == NULL) re原创 2021-05-01 11:22:26 · 1489 阅读 · 5 评论 -
力扣---二叉树的前序遍历
力扣—二叉树的前序遍历题目要求:给你二叉树的根节点 root ,返回它节点值的前序遍历。(题目来源:力扣)int TreeSize(struct TreeNode* root) { return root == NULL? 0 : TreeSize(root->left)+TreeSize(root->right)+1; } void preorder(struct TreeNode* root,int* arr,int* i) { if(ro原创 2021-05-01 11:13:52 · 243 阅读 · 0 评论 -
二叉树的最大深度
二叉树的最大深度题目描述:给定一个二叉树,找出其最大深度。二叉树的深度为根节点到最远叶子节点的最长路径上的节点数。说明: 叶子节点是指没有子节点的节点。(题目来源:力扣)思路:左的深度和右的深度比较大小,大的+1方法一:int maxDepth(struct TreeNode* root){ if(root == NULL) return 0; return maxDepth(root->left) > maxDepth(root->right原创 2021-05-01 10:43:06 · 93 阅读 · 0 评论 -
单值二叉树
单值二叉树题目要求:如果二叉树每个节点都具有相同的值,那么该二叉树就是单值二叉树。只有给定的树是单值二叉树时,才返回 true;否则返回 false。(题目来源:力扣)方法:递归bool isUnivalTree(struct TreeNode* root){ if(root == NULL) return true; if(root->left && root->left->val != root->val)原创 2021-05-01 10:23:10 · 145 阅读 · 0 评论 -
二叉树
二叉树二叉树的存储结构1、顺序存储:用数组来存储,只适用于完全二叉树(堆),因为会存在空间浪费,现实中只有堆才会用数组来存储。二叉树顺序存储在物理上是数组,在逻辑上是一颗二叉树。2.链式存储:用链表来表示一颗二叉树。二叉树的遍历四种遍历顺序:1、前序遍历 先根遍历 根 -> 左 -> 右2、中序遍历 中根遍历 左 -> 根 -> 右3、后序遍历 后根遍历 左 -> 右 -> 根4、层序遍历普通二叉树增删查改没有意义,如果是为了存储原创 2021-05-01 10:15:12 · 610 阅读 · 10 评论 -
TOP-K问题
TOP-K在题中的应用题目描述:(题目来源:力扣)思路1:排序0(N*logN)int* getLeastNumbers(int* arr, int arrSize, int k, int* returnSize){ HP hp; HeapInit(&hp,arr,arrsize); int* retarr = (int*)malloc(sizeof(int)*k); for(int i = 0;i < k;i++) { reta原创 2021-04-27 20:07:24 · 192 阅读 · 1 评论 -
建堆
建堆文章目录建堆计算建堆的复杂度实现建堆初始化建堆交换销毁插入数据向上调整删除数据获得堆顶数据堆里数据的个数判断是否为空打印计算建堆的复杂度堆排序优于直接选择排序(N^2)才有价值当堆排序(N-logN)的N过大时,logN可以忽略不记,即为O(N)实现建堆#include <stdio.h>#include <stdlib.h>#include <assert.h>#include <stdbool.h>#include <str原创 2021-04-27 19:30:55 · 174 阅读 · 0 评论 -
堆(堆排序)---完全二叉树
堆(一)堆1、定义:堆(heap)是计算机科学中一类特殊的数据结构的统称。堆通常是一个可以被看做一棵树的数组对象。假设父亲的下标是parentleftchild = parent * 2+1rightchild = parent * 2+22、性质a.堆中某个结点的值总是不大于或不小于其父结点的值;b.堆总是一棵完全二叉树。(二)分类1、小根堆:父亲小于等于孩子2、大根堆:父亲大于等于孩子(三)实现堆排序(小堆)void Swap(int* a,int* b){ int原创 2021-04-23 20:00:37 · 1924 阅读 · 0 评论 -
顺序队列实现小数进制转换
#include <stdio.h>#include <stdlib.h>#define MAXSIZE 100typedef struct{ int data[MAXSIZE]; int front,rear;}SeqQueue;int InitQueue(SeqQueue *Q){ Q->front=Q->rear=-1; return 1;}int IsEmpty(SeqQueue *Q){ if(Q->fro原创 2021-04-22 22:24:12 · 587 阅读 · 0 评论 -
树和二叉树
树(一)树1、树的定义:树是一种数据结构,它是由n(n>=1)个有限节点组成一个具有层次关系的集合。把它叫做“树”是因为它看起来像一棵倒挂的树,也就是说它是根朝上,而叶朝下的。2、特点:每个节点有零个或多个子节点;没有父节点的节点称为根节点;每一个非根节点有且只有一个父节点;除了根节点外,每个子节点可以分为多个不相交的子树(二)基本概念1、空集合也是树,称为空树。空树中没有节点;2、孩子节点或子节点:一个节点含有的子树的根节点称为该节点的子节点;3、节点的度:一个节点含有的子节点的原创 2021-04-23 12:53:40 · 403 阅读 · 4 评论 -
设计循环队列
设计循环队列题目描述:设计你的循环队列实现。 循环队列是一种线性数据结构,其操作表现基于 FIFO(先进先出)原则并且队尾被连接在队首之后以形成一个循环。它也被称为“环形缓冲器”。循环队列的一个好处是我们可以利用这个队列之前用过的空间。在一个普通队列里,一旦一个队列满了,我们就不能插入下一个元素,即使在队列前面仍有空间。但是使用循环队列,我们能使用这些空间去存储新的值。你的实现应该支持如下操作:MyCircularQueue(k): 构造器,设置队列长度为 k 。Front: 从队首获取元素。如原创 2021-04-21 12:47:43 · 332 阅读 · 1 评论 -
用栈实现队列
用栈实现队列题目描述(题目来源:力扣)思路:typedef struct { Stack pushST; Stack popST;} MyQueue;/** Initialize your data structure here. */MyQueue* myQueueCreate() { MyQueue*q =(MyQueue*) malloc(sizeof(MyQueue)); StackInit(&q->popST); Stack原创 2021-04-19 19:43:44 · 101 阅读 · 0 评论 -
找链表中间节点
单链表----找链表的中间节点//给定一个头结点为 head 的非空单链表,返回链表的中间结点。//如果有两个中间结点,则返回第二个中间结点。原创 2021-04-11 09:26:32 · 228 阅读 · 0 评论 -
移出链表元素
单链表—移除链表元素//给你一个链表的头节点 head 和一个整数 val ,请你删除链表中所有满足 Node.val == val 的节点,并返回 新的头节点 。方法一:不带头指针方法二:带头指针原创 2021-04-11 09:21:55 · 131 阅读 · 0 评论 -
翻转链表
单链表—翻转链表的两种方法*1.迭代:使用三个指针翻转:2.头插法(注:这里的头插不创建新节点)//依次取原链表中的节点头插到新节点原创 2021-04-11 09:06:44 · 121 阅读 · 0 评论 -
顺序表
@[TOC]顺序表顺序表的接口顺序表具体实现三级目录原创 2021-04-03 17:30:36 · 147 阅读 · 0 评论 -
用队列实现栈
用队列实现栈题目描述:请你仅使用两个队列实现一个后入先出(LIFO)的栈,并支持普通栈 的全部四种操作(push、top、pop 和 empty)。实现 MyStack 类:void push(int x) 将元素 x 压入栈顶。int pop() 移除并返回栈顶元素。int top() 返回栈顶元素。boolean empty() 如果栈是空的,返回 true ;否则,返回 false注意:你只能使用队列的基本操作 —— 也就是 push to back、peek/pop from原创 2021-04-18 13:25:04 · 167 阅读 · 0 评论 -
判断字符串中左右括号是否匹配(运用栈)
判断字符串中左右括号是否匹配题目描述:给定一个只包括 ‘(’,’)’,’{’,’}’,’[’,’]’ 的字符串 s ,判断字符串是否有效。有效字符串需满足:1、左括号必须用相同类型的右括号闭合。2、左括号必须以正确的顺序闭合。题目来源:力扣(LeetCode)bool isValid(char * s){ Stack st; StackInit(&st); while(*s) { //左括号入栈 //右括号找最近的左括号匹原创 2021-04-18 13:00:49 · 2401 阅读 · 0 评论 -
队列
1、队列的概念队列:只允许在一端进行插入数据操作,在另一端进行删除数据操作的特殊线性表,队列具有先入先出FIFO(First in First out)的特点入队列:进行插入操作的一端称为队尾出队列:进行删除操作的一端称为队头2、队列的实现创建//用链表实现#pragma once#include <stdbool.h>#include <assert.h>#include <stdlib.h>#include <stdio.h>原创 2021-04-18 12:36:12 · 179 阅读 · 0 评论 -
栈
1.栈的概念栈:一种特殊的线性表,只允许在固定的一端进行插入和删除元素操作,进行数据插入和删除的一端称为栈顶,另一端称为栈底。栈中的数据元素遵循LIFO(Last in First out)的原则压栈:栈的插入操作叫做压栈/进栈/入栈,入数据在栈顶出栈:栈的删除操作叫出栈。出数据也在栈顶2、栈的实现创建//用数组的方式实现栈#pragma once#include <stdio.h>#include <stdbool.h>#include <asser原创 2021-04-18 12:16:57 · 275 阅读 · 0 评论 -
顺序表和链表的总结
顺序表和链表(双向带头循环)的优缺点对比*顺序表的优点按下标进行随机访问cpu高速缓存命中率比较高(物理空间是连续的)顺序表的缺点:空间不够需要增容,(一定程序的行能消耗)可能存在一定的空间浪费在头部或中间插入删除数据,效率比较低O(N)链表的优点:按需申请内存,需要一个数据就申请一块内存,也不存在空间浪费任意位置O(1)时间内插入,删除数据链表的缺点不支持下标的随机访问...原创 2021-04-18 11:50:58 · 302 阅读 · 0 评论 -
进制转换
进制转换方法:利用栈的特点(后进先出)举例:10 转换2进制----->1010步骤实现#include <stdio.h>#include <stdlib.h>#define MAXSIZE 100typedef struct stack{ int data[MAXSIZE]; int top;}SeqStack;void InitStack(SeqStack* s){ s->top = -1;}int EmptyStack(SeqS原创 2021-04-17 12:58:39 · 123 阅读 · 0 评论 -
删除链表中重复节点
删除链表中的重复结点题目描述:在一个排序的链表中,存在重复的结点,请删除该链表中重复结点,重复的结点不保留,返回链表头指针。(没有头节点) 例如,链表1->2->3->3->4->4->5 处理后为 1->2->5(题目转载自牛客网)思路:用三个指针 prev,cur,next。prev先为空。cur 指向第一个节点,next指向phead的下一个节点,若next->val==cur->val就继续往下找,直到val不相等然后删除cu原创 2021-04-17 12:18:54 · 151 阅读 · 0 评论 -
判断链表是否为回文(2)
**判断链表是否为回文链表(运用出栈入栈的方法)**思路:1、找到中间节点2、把中间节点以前的节点入栈3、节点出栈,并于中间节点以后的节点比较,若是值相同就是回文结构(栈的特点:后进先出)若是链表个数为奇数,找到中间节点P的下一个节点P->next再做比较#include <stdio.h>#include <stdlib.h>#define MAXSIZE 100typedef struct node//链表{ char data; stru原创 2021-04-17 11:14:23 · 187 阅读 · 0 评论 -
链表插入排序
插入排序算法:插入排序是迭代的,每次只移动一个元素,直到所有元素可以形成一个有序的输出列表。每次迭代中,插入排序只从输入数据中移除一个待排序的元素,找到它在序列中适当的位置,并将其插入。重复直到所有输入数据插入完为止。来源:力扣(LeetCode)struct ListNode* insertionSortList(struct ListNode* head){ if(head == NULL||head->next == NULL) return head;原创 2021-04-17 10:18:17 · 100 阅读 · 0 评论