数据结构
夏天的呆子
这个作者很懒,什么都没留下…
展开
-
树&二叉树
关于树的概念: a.节点:结点包含数据和指向其它节点的指针。 b.根节点:树第一个结点称为根节点。 c.结点的度:结点拥有的子节点个数。 d.叶节点:没有子节点的节点(度为0)。 e.父子节点:一个节点father指向另一个节点child,则child为孩子节点,father为父亲节点 。 f.兄弟节点:具有相同父节点的节点互为兄弟节点。 g.节点的祖先:从根节点开始到该节点所经原创 2017-04-04 16:58:39 · 214 阅读 · 0 评论 -
/*****/栈和队列常见面试题
1.实现一个栈,要求实现Push(出栈)、Pop(入栈)、Min(返回最小值的操作)的时间复杂度为O(1) 因为栈的特点就是“先进后出,后进先出”,而且只能在栈顶进行操作,所以Push和Pop的时间复杂度就是O(1),要返回最小值的话,可以用一个数组(或栈)记录栈中前n项的最小值,以空间换时间,这样的话就能在O(1)内返回最小值了。 template<typename原创 2017-05-16 09:44:01 · 289 阅读 · 0 评论 -
/*****/单链表常见面试题
1.比较顺序表和链表的优缺点,说说它们分别在什么场景下使用? 1)顺序表支持随机访问,单链表不支持随机访问。 2)顺序表插入/删除数据效率很低,时间复杂度为O(N)(除尾插尾删),单链表插入/删除效率更高,时间复杂度为O(1)。 3)顺序表的CPU高速缓存效率更高,单链表CPU高速缓存效率低。 2.从尾到头打印单链表 逆序打印单链表(递归) 代码: List原创 2017-07-05 11:32:43 · 376 阅读 · 0 评论 -
/***/面试题:求相交链表的交点
链表相交的情况,如图: 方法一 分别统计两条链表的长度s1和s2,假设s1大于s2,则我们让head1先走上s1-s2步,让后再让head2也出发,则它们的相遇点就是交点。 pLinkNode GetEntryCycle(pLinkNode head, pLinkNode meet) { pLinkNode cur = head->next; pLinkNo原创 2017-05-22 10:56:31 · 321 阅读 · 0 评论 -
/*****/二叉树基础问题
创建一棵二叉树(先序创建): 以{1,2,3,’#’,’#’,4,’#’,’#’,5,6}为例: 先创建左路,每创建一个结点就入栈,cur指向当前结点: 左路创建完毕之后用一个变量top保存栈顶元素3,然后将栈顶的元素3抛出: 然后再创建top的右子树且cur=top->_right,然后再重复上述操作,直到创建完毕。 非递归: TreeNonR(c原创 2017-08-29 13:00:58 · 208 阅读 · 0 评论 -
/***/二叉树经典面试题之判断一棵二叉树是否是完全二叉树
什么是完全二叉树呢 如果一颗二叉树的只有最后两层结点的度能小于2,其余结点的度都等于2。且最后一层的结点从最左边依次排列。 如果一颗二叉树中的每一个结点都与编号从1到n的满二叉树中的结点一一对应,则称这棵二叉树为完全二叉树。 我们可以根据完全二叉树的定义,按照层序遍历一颗树,当遇到空结点时如果这棵树已经遍历完毕,则这棵树就是完全二叉树,如果遇到空结点的后面还有元素则这原创 2017-05-15 10:18:49 · 1500 阅读 · 1 评论 -
/*****/二叉树经典面试题
以下二叉树的结点类型如下:template<typename T> struct BinaryTreeNode { T _data; BinaryTreeNode<T> *_left; BinaryTreeNode<T> *_right; BinaryTreeNode(const T& data = T()) :_data(原创 2017-05-15 11:43:56 · 188 阅读 · 0 评论 -
/*****/关于堆
关于最大堆与最小堆: 如果所有父节点的关键码都小于或等于孩子的关键码,则称最小堆。 如果所有父节点的关键码大于或等于孩子的关键码,则称最大堆。 堆的性质: 1、可以通过一个简单的数组实现 2、支持最坏情况为O(logN)的insert和deleteMin 3、支持常量平均时间的insert操作以及常量平均最坏时间的findMin操作。 4、二叉堆原创 2017-04-17 09:03:02 · 246 阅读 · 0 评论 -
/*****/关于图1.0
其他一些概念: 完全图:在由n个顶点组成的无向图中,若有N(N-1)/2条边,则成为无向完全图。(也就是说任意两个点都有路径) 边的权重:权重表示对边赋予的权值。 邻接顶点:如果两个顶点之间有边,则这两个顶点就互为邻接顶点。 度:与顶点v关联的边的数目称为顶点v的度。 路径:在图G=(V,E)中,若从顶点v1出发,沿着边经过若干顶点v2、v3…到v8,则(v1,v2…v8)就是顶点v1到顶原创 2017-05-24 10:19:14 · 218 阅读 · 0 评论 -
/*****/关于图2.0
最小生成树(无向图): 一个连通图,图中有N个顶点。我们能在连通图中选取N-1条边将图的所有顶点连在一起且不构成回路,则这N-1条边就构成了一个生成树。如果这N-1条边的权值和最小,则就构成了最小生成树。 构造最小生成树时有两个算法,Kruskal算法和Prim算法,都使用了贪心法求解。 注意:使用贪心算法在求解最小生成树的时候总是得到了局部最优解,但是整体结果不一定最优解。Krus原创 2017-05-24 10:37:21 · 167 阅读 · 0 评论 -
/*****/AVL树&红黑树
AVL树: AVL树是高度平衡的二叉搜索树,它能保持二叉树的高度平衡,尽量降低二叉树的高度平衡,减少树的平均搜索长度。原创 2017-04-09 12:51:40 · 349 阅读 · 0 评论 -
/*****/跳表
跳表的原理非常简单,跳表其实就是一种可以进行二分查找的有序链表。跳表的数据结构模型如图:原创 2017-09-06 20:53:35 · 197 阅读 · 0 评论 -
/*****/BloomFilter(布隆过滤器)
#pragma once #include<vector> using namespace std; struct _HashFunc1 { size_t operator()(const string& str) { size_t num=0; for (int i = 0; i < (int)str.size();i+原创 2017-09-06 21:03:30 · 211 阅读 · 0 评论 -
/*****/并查集
在一个有N个元素的集合问题中,我们通常是让每个元素构成一个单元素的集合,然后按一定顺序将属于同一集合的元素进行合并。在此过程中要不断的查询某个元素归属于哪个集合,适合于描述这类问题的抽象数据类型我们称之为并查集。 实际应用: 已知有n个人和m对好友关系,并且这些好友关系存储在r里面,如果两个人是直接或间接的好友,则认为他们属于同一个朋友圈。 n=5,m=3,r={{1,2},{2,3}原创 2017-05-22 08:03:07 · 218 阅读 · 0 评论 -
栈和队列
栈的定义–Stack 栈只允许在末端进行插入和删除的线性表。栈具有后进先出的特性(LIFO,Last In First Out)。栈的应用 1.算术表达式求值。波兰表达式(后缀表达式) 2.迷宫问题 3.栈模拟压栈,实现递归转非递归。 #pragma once// 静态栈 //template<class T, size_t N = 100> //class Stack //{ //publ原创 2017-05-15 08:57:51 · 258 阅读 · 0 评论 -
堆的基本代码
#include<iostream> #include<vector> #include<assert.h> using namespace std; template<class T> //利用仿函数,可以完成代码的复用,这里我们假设建立大堆。 struct Greater { bool operator()(const T& x1, const T& x2)原创 2017-09-05 22:23:28 · 503 阅读 · 1 评论 -
堆的应用之堆排序
void AdjustDown1(int* b, int n, int i) //向下调整,建立大堆 { int parent = i; int child = parent * 2 + 1; while (child < n) { if (child + 1 < n&&b[child + 1] > b[child])原创 2017-09-05 22:19:52 · 213 阅读 · 0 评论 -
栈帧&栈&递归
一般函数的调用栈帧 递归函数调用栈帧 函数栈帧调用&数据结构栈–栈实现将递归程序转换为非递归程序原创 2017-05-15 09:03:13 · 667 阅读 · 0 评论 -
矩阵
对称矩阵及对称矩阵的压缩存储 设一个N*N的方阵A,A中任意元素Aij,当且仅当Aij == Aji(0 <= i <= N-1 && 0 <= j <= N-1),则矩阵A是对称矩阵。以矩阵的对角线为分隔,分为上三 角和下三角。 压缩存储称矩阵存储时只需要存储上三角/下三角的数据,所以最多存 储n(n+1)/2个数据。 对称矩阵和压缩存储的对应关系:下三角存储i>=j, Symmetric原创 2017-05-15 09:07:13 · 395 阅读 · 0 评论 -
广义表
广义表是非线性的结构,是线性表的一种扩展,是有n个元素组成有限序列。 广义表的定义是递归的,因为在表的描述中又得到了表,允许表中有表。原创 2017-05-15 09:14:54 · 166 阅读 · 0 评论 -
堆及其应用
应用1.优先级队列优先级队列 是不同于先进先出队列的另一种队列。每次从队列中取出的是具有最高优先权的元素。#pragma once #include <cassert> #include <iostream> #include <cstdlib> #include "Heap.h" using namespace std;template <class T , class Compare = Gre原创 2017-05-15 09:38:12 · 144 阅读 · 0 评论 -
位图
C++代码实现#pragma once #include <iostream> #include <vector> using namespace std;class BitMap { public: BitMap(size_t range) //给定位图所能表示的 范围 { _bitmap.resize(range / 32 + 1); //设置大小原创 2017-05-15 09:42:29 · 204 阅读 · 0 评论 -
单链表和顺序表的实现
单链表实现://函数声明:"linklist.h" #define _CRT_SECURE_NO_WARNINGS 1 #include<stdio.h> #include<stdlib.h> typedef int ElemType; typedef struct linknode { ElemType data; struct linknode *原创 2017-05-15 09:51:27 · 377 阅读 · 0 评论 -
双向单链表的实现
#include"twowaylinklist.h" #define _CRT_SECURE_NO_WARNINGS 1 #include<stdio.h> #include<stdlib.h> typedef int ElemType; typedef struct DulNode { struct DulNode *prior; ElemType d原创 2017-05-15 09:57:13 · 227 阅读 · 0 评论 -
面试题: 二叉搜索树转换成有序双向链表
因为二叉搜索树的中序遍历是有序的,所以以中序遍历实现,要是双向链表,我们可以将结点的左孩子转换成前驱指针,结点的右孩子转换成后继指针。(可以用一个prev指针来记录前一个结点,然后把prev的right(后继)指向cur,把cur的left(前驱)指向prev,之后再更新prev的值。)template<typename T> class TreeToList { type原创 2017-05-22 08:07:08 · 298 阅读 · 0 评论 -
关于单链表的基本操作
在顺序表中,我们需要头插或者在顺序表的中间位置插入元素时,就必须将后面的元素一一后移,再将需要插入的元素插入进去。可是这样的效率明显很低,所以就想到了单链表这种数据结构,可以将在物理地址上不连续的数据连接起来,需要连接,那么就需要有一个保存下一个元素地址的指针,可是没有这样的内置类型供我们使用,所以这时就需要我们自定义一个类型,在C语言中我们可以使用结构体来构造。 1.初始化单链表原创 2017-07-15 17:24:05 · 266 阅读 · 0 评论 -
堆的应用之TOP K问题
此问题需要在N个数中找出最大或者最小的K 个数。这里我们用找最大的K个数来举例。void AdjustDown(int* hp, int K, int i) { int parent = i; int child = i * 2 + 1; while (child < K) { if (child + 1 < K&&hp[chi原创 2017-09-05 22:18:45 · 181 阅读 · 0 评论 -
/*****/排序
直接插入排序 插入排序的基本思想是: 每次将一个待排的记录,按照其关键字的大小,插入到前面已经排好序的有序区中适当的位置,直到全部记录插入完毕为止。 假设待排序的记录存放在数组R[0..n]中,初始时R[0]是一个有序区,R[1..n]是无序区,从i=1开始,依次将R[i]插入到有序区R[0..i-1]中,生成一个包含n个记录的有序区。 Sort.h#pragma o原创 2017-08-07 14:24:32 · 383 阅读 · 0 评论