数据结构是计算机存储、组织数据的方式。数据结构是指相互之间存在一种或多种特定关系的数据元素的集合。通常情况下,精心选择的数据结构可以带来更高的运行或者存储效率。数据结构往往同高效的检索算法和索引技术有关。
前言 数据结构还是大二的时候学过的,当然由于是非计算机专业的学生,所以学的也不怎么样,去年用c++实现了最基本的数据结构,链表/栈/队列/二叉树,三月份看的时候还贴到了博客上。然而当时由于代码量不够,其实写的并不是很好,理解也太不到位。 最近在看算法导论,当然最基本的就是数据结构,于是打算将基本的知识在回顾一下。 我是一个疯狂的人,一旦决定做一件事,就会全天埋头去干,因为总有一种恨不得赶快学完的感
对于一个int数组,请编写一个冒泡排序算法,对数组元素排序。 给定一个int数组A及数组的大小n,请返回排序后的数组。 测试样例: [1,2,3,5,2,3],6 [1,2,2,3,3,5] class BubbleSort { public: void swap(int * a, int * b){ int temp = *a; *a = *b;
对于一个int数组,请编写一个归并排序算法,对数组元素排序。 给定一个int数组A及数组的大小n,请返回排序后的数组。 测试样例: [1,2,3,5,2,3],6 [1,2,2,3,3,5] 思路: 1, 选取第一个为哨兵,不要随机选取 2, 在交换的时候一定要注意偏移量,left一定要加上,不然通不过测试。 3, 统计完小于哨兵的counter后,交换一次key和A[counter]即可。 #i
二叉树首先是一棵树,每个节点都不能有多于两个的儿子,也就是树的度不能超过2。二叉树的两个儿子分别称为“左儿子”和“右儿子”,次序不能颠倒。如图1是一个简单的二叉树。 二叉树的种类 一种是满二叉树,除了最后一层的叶子节点外,每一层的节点都必须有两个儿子节点。如图2是一个满二叉树。 另一种是完全二叉树,一棵二叉树去掉最后一层后剩下的节点组成的树为满二叉树,最后一层的节点从左到右连续,没有空出的节点,这
//栈的定义 //这里存在一个问题:堆和栈的区别 //栈是一个后进先出的线性表(这里就可以知道了线性表中顺序表和链表即可以自己操作数据,同时也是其他数据结构的基础,例如栈、队列的基础) //堆栈在眼前的认知中就好比是洗盘子,队列就好比是队列,先进先出 //栈分栈顶(表尾)和栈尾(表头),栈只能在栈顶进行操作,出栈或者进栈都是在栈顶操作。这是和一般的线性表区别的地方 //既然栈作为线性表,那么其就可
1. 概述 堆(也叫优先队列),是一棵完全二叉树,它的特点是父节点的值大于(小于)两个子节点的值(分别称为大顶堆和小顶堆)。它常用于管理算法执行过程中的信息,应用场景包括堆排序,优先队列等。 2. 堆的基本操作 堆是一棵完全二叉树,高度为O(lg n),其基本操作至多与树的高度成正比。在介绍堆的基本操作之前,先介绍几个基本术语: A:用于表示堆的数组,下标从1开始,一直到n PARENT(t):节
二叉树总结 1. 二叉树的重要性质 一个二叉树的第i层最多有 2i−1 个结点(i>=1) 深度为k的二叉树最多有 2k−1 个结点(k>=1) 对于任何非空二叉树有 n0 个叶结点, n2 个度为2的结点,那么总有关系: n0=n2+1 2.对二叉树的操作 Boolean IsEmpty(BinTree BT);//判断BT是否为空。 void Traversal(BinTree BT);//遍
数据结构队列Queue function Queue() { // 数据存储 this.dataStore = []; } Queue.prototype = { constructor: Queue, add: function(array) { this.dataStore = array; }, // 排列 enqueue: function( elem
栈结构:先进后出,后进先出,只允许在栈尾操作。 队列:先进先出,在队尾入队,在队头出队。 要想用两个栈实现一个队列,就需要使用一个相当于中间量的结构进行队列的入队和出队操作。 用图形象化为: 这样问题就从图中得出了思路: 入队操作:把入队元素一一存入一个栈结构中即可。 出队操作:出队时,先判断另一个栈结构中是否有元素,若有先将元素出栈Pop();若为空,则把栈S1中的元素全部倒入Push()栈S2
以前,我们实现一个栈,轻轻松松,无需考虑太多因素,即可实现。 现在,要求在一个数组里实现两个栈,那么在数组里怎么实现栈呢? 无非就是下标索引,方法也不局限一种,例如:用奇数下标作为栈s1的结构,用偶数作为s2的结构;再者:一前一后的结构,栈s1从前往后,栈s2从后往前。 本人只想到了使用这两中方法实现,当然,这两种方法各有利弊。 第一种方法,倘若其中一个栈只入了一个元素,而另一个入了很多元素,那么
栈结构,通俗易懂,特点:先进后出,后进先出。 以下,仅对于栈结构常用的操作进行实现 包括:         入栈(push),出栈(pop),判空(empty),栈顶元素(GetTop) #include <iostream> using namespace std; template<class T> class Stack { public:     Stack(T size) // 初始化
二叉树概念 在计算机科学中,二叉树是每个节点最多有两个子树的树结构。通常子树被称作“左子树”(left subtree)和“右子树”(right subtree)。二叉树常被用于实现二叉查找树和二叉堆。 二 叉树的每个结点至多只有二棵子树(不存在度大于2的结点),二叉树的子树有左右之分,次序不能颠倒。二叉树的第i层至多有2^{i-1}个结点;深度为k 的二叉树至多有2^k-1个结点;对任何一棵二叉
    首先先看一下下面这个腾讯的面试题: 给40亿个不重复的无符号整数,没排过序。给一个无符号整数,如何快速判断一个数是否在这40亿个数中。 【腾讯】 思路一:     最容易想到的解法就是遍历所有的40多亿个整数,然后一个一个判断。但是这个需要花费的内存是多大呢?     大家可以去算一下,这里我就直接给出结果为16G,是不是需要的空间很大啊。如果面试官给出限制条件,要你使用的空间少于多少,遍
● 直接插入排序(Insert Sort) 1、算法描述:     该算法是一种简单直观的是通过构建有序序列,对于未排序数据,在已排序序列中从后向前扫描,找到相应位置并插入。插入排序在实现上只需用到O(1)的额外空间的排序,因而在从后向前扫描过程中,需要反复把已排序元素逐步向后挪位为最新元素提供插入空间。 2、步骤: 1)从第一个元素开始,该元素可以认为已经被排序 2)取出下一个元素,在已经排序的
● 快速排序(Quick Sort) 1、算法描述:    在平均状况下,排序n个数据要O(nlg(n))次比较。在最坏状况下则需要O(n^2)次比较,但这种状况并不常见。事实上,快速排序通常明显比其他O(nlg(n))算法更快,因为它的内部循环(inner loop)可以在大部分的架构上很有效率地被实现出来,且在大部分真实世界的数据,可以决定设计的选择,减少所需时间的二次方项的可能性。 2、步骤
计数排序: #define _CRT_SECURE_NO_WARNINGS 1 #include<iostream> using namespace std; #include<assert.h> #include<vector> void Print(vector<int>  a) {     for (int i = 0; i < a.size(); i++)     {         
● 计数排序 1、算法思想:        计数排序是直接定址法的变形。通过开辟一定大小的空间,统计相同数据出现的次数,然后回写到原序列中。 2、步骤: 1)找到序列中的最大和最小数据,确定开辟的空间大小。 2)开辟空间,利用开辟的空间存放各数据的个数。 3)将排好序的序列回写到原序列中。 具体实现如下: void CountSort(int *arr, int size) {  assert(a
● 二叉搜索树满足以下条件的二叉树: 1、每个节点都有一个作为搜索依据的关键码(key),所有节点的关键码互不相同。 2、左子树上所有节点的关键码(key)都小于根节点的关键码(key)。 3、右子树上所有节点的关键码(key)都大于根节点的关键码(key)。 4、左右子树都是二叉搜索树。 ● 二叉搜索树的插入过程如下: 1、若当前的二叉搜索树为空,则插入的元素为根节点。 2、若插入的元素值小于根
● 二叉搜索树满足以下条件的二叉树: 1、每个节点都有一个作为搜索依据的关键码(key),所有节点的关键码互不相同。 2、左子树上所有节点的关键码(key)都小于根节点的关键码(key)。 3、右子树上所有节点的关键码(key)都大于根节点的关键码(key)。 4、左右子树都是二叉搜索树。 ● 二叉搜索树的插入过程如下: 1、若当前的二叉搜索树为空,则插入的元素为根节点。 2、若插入的元素值小于根
1、AVL树简介       AVL树本质上还是一棵二叉搜索树,又称高度平衡的二叉搜索树。它能保持二叉树的高度平衡,尽量降低二叉树的高度,减少树的平均搜索长度。对于二叉搜索树的介绍和实现,可查看本人上一篇博客。 2、AVL树的特点 1)本身首先是一棵二叉搜索树。  2)带有平衡条件:每个结点的左右子树的高度之差的绝对值(平衡因子)最多为1。 3)树中的每个左子树和右子树都是AVL树。 4)每个结点
1、AVL树简介       AVL树本质上还是一棵二叉搜索树,又称高度平衡的二叉搜索树。它能保持二叉树的高度平衡,尽量降低二叉树的高度,减少树的平均搜索长度。对于二叉搜索树的介绍和实现,可查看本人上一篇博客。 2、AVL树的特点 1)本身首先是一棵二叉搜索树。  2)带有平衡条件:每个结点的左右子树的高度之差的绝对值(平衡因子)最多为1。 3)树中的每个左子树和右子树都是AVL树。 4)每个结点
        就是一个翻牌子的问题,写的略繁琐,因为只是实验室水题,所以不优化了,L是从最左翻面并且覆盖到第二堆上,以此类推,模拟就好。 #include "stdio.h" #include "stack" #include "queue" using namespace std; int main(int argc, char const *argv[]) { int n;
其实就是对于操作符进行重载,然后用个优先队列,水之。  还有先后顺序的优先级不要问了。    #include <iostream> #include <queue> #include <algorithm> #include <cstring> using namespace std; struct node { char name[1000]; int parameter; int
红黑树是一棵二叉搜索树,它在每个节点上增加了一个存储位来表示节点的颜色,可以是Red或Black。通过对任何一条从根到叶子简单路径上的 颜色来约束,红黑树保证最长路径不超过最短路径的两倍,因而近似于平衡。 红黑树是满足下面红黑性质的二叉搜索树 每个节点,不是红色就是黑色的 根节点是黑色的 如果一个节点是红色的,则它的两个子节点是黑色的(没有连续的红节点) 对每个节点,从该节点到其所有后代叶节点的简
二叉搜索树的性质: 每个节点都有一个作为搜索依据的关键码(key),所有节点的关键码互不相同。 左子树上所有节点的关键码(key)都小于根节点的关键码(key)。 右子树上所有节点的关键码(key)都大于根节点的关键码(key)。 左右子树都是二叉搜索树。 //BSTree.h #pragma once template<class K,class V> struct BSTreeNode
位图(bitmap),就是用一块内存区域的每个比特表示一个对象的数据结构。 优点是速度快,内存空间占用小,能表示大范围的数据。 假设要对0到一千万范围内的、没有重复元素的正整数排序,则利用位图数据结构很合适。 应用场景: 给40亿个不重复的无符号整数,没排过序。给一个无符号整数,如何快速判断一个数是否在这40亿个数中。 思路:如果内存够的话,40亿个整型使用位图存储需要500M左右的空间。 #pr
布隆过滤器(Bloom Filter)是由布隆(Burton Howard Bloom)在1970年提出的。 它实际上是由一个很长的二进制向量和一系列随机映射函数组成,布隆过滤器可以用于检索一个元素是否在一个集合中。它的优点是空间效率和查询时间都远远超过一般的算法,缺点是有一定的误识别率和删除困难,但是没有识别错误的情形。 在日常生活中,包括在设计计算机软件时,我们经常要判断一个元素是否在一个集合
 树        树是一种典型的非线性数据结构,它能够很好地应用于描述分支和层次特性的数据集合,是由一个或多个结点组成的有限集合T,一棵树至少有一个结点。           树的度, 一个结点的子树数目就是该结点的“度”,在这个结点下面直接与这个结点连着的结点数目就是这个结点的度。一颗数的度数等于这颗树中各结点度的最大值。        树的层次,根结点层次为1,往下依次加1。        
选择一个基准元素,通常选择第一个元素或者最后一个元素,通过一趟扫描,将待排序列分成两部分,一部分比基准元素小,一部分大于等于基准元素, 此时基准元素在其排好序后的正确位置,然后再用同样的方法递归地排序划分的两部分。 public class quickSort { inta[]={49,38,65,97,76,13,27,49,78,34,12,64,5,4,62,99,98,54
二叉搜索树,又叫二叉排序树,二叉查找树。它有以下特点: 左子树的值小于根节点的值,右子树的值大于根节点的值;二叉搜索树中序遍历的结果 就是一个升序序列。 当然,空树也是一个二叉搜索树。 全局满足二叉搜索树的性质,局部也应该满足。 既然有以上性质,那么二叉树的查找是相当方便的,当然插入和删除,复杂度也会明显 降低。 查找:从根节点开始,如果要插入的key小于根节点的key,则向左走,否则向右走,找