数据结构和算法
文章平均质量分 56
gogogo_sky
不积跬步,无以致千里;不积小流,无以成江海
展开
-
实现一个返回最小值的栈
一、 实现一个栈,要求实现Push(出栈)、Pop(入栈)、Min(返回最小值的操作) 的时间复杂度为O(1) (1)栈的基本操作入栈(push);出栈(pop);查找栈顶(top);栈的元素个数(size);检查栈是否为空(empty);我们知道入栈(push)和出栈(pop)时间复杂度本身就为O(1);所以只要让Min(返回最小值操作)的时间复杂度为O(1)即可; (2)Min(返回最小值操原创 2017-04-15 23:01:56 · 1372 阅读 · 0 评论 -
非比较排序---【归并排序】
一、归并排序的思想 归并排序利用了分冶的思想,将一块待排序的区间,取中间位置,分成两段区间;然后通过不断的递归,直到每段区间只有一个数字,这时我们就认为该段区间有序,然后将这相邻的两段有序区间合并为一个有序区间; 这样通过递归先分裂数组,然后再合并数组,就完成了归并排序; 二、代码实现#include<iostream>#include<cassert>using namespace s原创 2017-07-21 17:04:25 · 331 阅读 · 0 评论 -
链表面试题(二)---链表逆序(链表反转)
一、结构体定义typedef int DataType;typedef struct ListNode//定义结点{ DataType data; struct ListNode* next;}ListNode,*PListNode;typedef struct PList//定义一个成员是指向结点的指针的结构体{ PListNode PHead;}PList,*P原创 2017-05-16 23:15:26 · 460 阅读 · 1 评论 -
链表面试题(十一)---求带环单链表 环的入口点
一、结构体定义typedef int DataType;typedef struct ListNode//定义结点{ DataType data; struct ListNode* next;}ListNode,*PListNode;typedef struct PList//定义一个成员是指向结点的指针的结构体{ PListNode PHead;}PList,*P原创 2017-05-17 01:37:18 · 333 阅读 · 0 评论 -
链表面试题(十)---求带环单链表的环的长度
一、结构体的定义typedef int DataType;typedef struct ListNode//定义结点{ DataType data; struct ListNode* next;}ListNode,*PListNode;typedef struct PList//定义一个成员是指向结点的指针的结构体{ PListNode PHead;}PList,*原创 2017-05-17 01:20:25 · 569 阅读 · 0 评论 -
【冒泡排序】
一、简介 冒泡排序时交换排序的一种; 它的总体思想是:从数列的第一个数开始,将数列的数字两两比较,使得大数在前,直到倒数第二个数和倒数第一个数作比较,然后使得大数在前;那么这一趟比较下来,就会把数列中最大的数冒泡到数列的最后面;下一趟冒泡只需要冒泡到倒数第二个,依次类推,直到某趟冒泡的元素剩下一个;冒泡完毕,排序完成 (1)普通写法 假设一个数组中有sz个元素,每趟冒泡会把1个元素放在正确的原创 2017-07-14 22:21:02 · 315 阅读 · 0 评论 -
【快速排序】★★★★★
一、快速排序的简介快速排序是一种总体上来讲时间复杂度较低的排序,其主要利用了分冶的思想;在排序一大段数据时,每次通过选取key值,然后利用不同的方法将该段数据分为两段(小于等于key的一段在一边,大于key的一段在一边,key的数据在这两段的中间);然后通过递归的方法分别对上述的左右两段数据采用同样的思想分段;快速排序每一趟下来,位于两段中间的key值就会被置于最终排序时该数据的正确位置,就是说快速原创 2017-07-12 02:33:04 · 3244 阅读 · 1 评论 -
【直接插入排序】和【希尔排序】
一、直接插入排序(1)算法步骤(升序)1>将待排序数组的第一个数拿出来看做一个已经排序好的有序区间;将后面的数列看做一个无序的待排序数列; 2>从有序数列的最后一个数开始和待排序数列的第一个数key比较(即有序数列的最后一个位置的下一个位置的数),如果有序数列的最后一个数大于key,则将有序数列的最后一个数填到key的位置;然后取有序数列的前一个数和key比较,大于key则填入后一个位置,继续取有原创 2017-07-13 16:23:45 · 519 阅读 · 0 评论 -
动态顺序表的实现(c语言版本)
一、前面实现的静态顺序表,虽然看起来也能储存数据,对表中数据进行管理;不过它是用大小固定的数组储存数据的;当数据太少的时候,空间用不完,浪费内存;当数据太多的时候;又会面临内存不足的麻烦;所以,静态顺序表不是很好;除非我们提前知道要储蓄管理的数据个数;要不然一定会面临空间用不完浪费或者空间太少不够用的情况;接下来;我们实现一个动态的顺序表;动态顺序表的底层实现是一个指向某个动态内存的指针;我们根据存原创 2017-04-27 22:32:31 · 558 阅读 · 0 评论 -
1000人通讯录的实现(静态实现)
实现一个通讯录;通讯录可以用来存储1000个人的信息,每个人的信息包括:姓名、性别、年龄、电话、住址 提供方法:1. 添加联系人信息2. 删除指定联系人信息3. 查找指定联系人信息4. 修改指定联系人信息5. 显示所有联系人信息6. 清空所有联系人7. 以名字排序所有联系人首先:建立一个头文件contacts.h#include #原创 2016-05-12 16:44:20 · 431 阅读 · 0 评论 -
通讯录的实现(动态实现)
在静态实现1000人通讯录的基础上,这次我们来动态实现,可以动态开辟内存空间,不受人数的限制,但此处的不受限制是相对的,如果内存用完了,那也不能再添加联系人了;这次我们在静态实现的基础上再次优化,使用了枚举,以及对每次执行完一个功能时的页面进行优化,让使用者不再麻烦的去看最顶上的操作目录;首先定义了头文件:contacts.h#include #include #inclu原创 2016-05-17 00:56:40 · 488 阅读 · 0 评论 -
顺序表的链式储存
#ifndef __LINKLIST_H__#define __LINKLIST_H__#include#include#includetypedef int DataType;typedef struct LinkNode{ DataType data; struct LinkNode* next;}LinkNode,*pLinkNode;typedef stru原创 2016-06-06 15:59:36 · 616 阅读 · 0 评论 -
二叉树的递归实现(前序,中序,后序,层序,高度,叶子节点数,第k层节点数)
一:二叉树是我们学过最常用也是最基础的数据结构,要想学好二叉树①首先要学会利用含有非法值得数组前序遍历★建立一颗二叉树;②然后我们要会用递归的方式对这颗二叉树进行★前序,★中序,★后序的遍历打印,也要学会利用队列的先进先出的原则对着棵树进行★层序访问;③然后我们还要知道这颗二叉树的基本信息;比如,★二叉树的总节点个数,★二叉树的叶子节点个数,★二叉树的第k层的节点个数,★二叉树的高度(深度); 二原创 2017-04-12 17:45:14 · 926 阅读 · 1 评论 -
HashTable【哈希表/散列表】
前序:一、关于查找,其实说白了,查找的本质就是已知对象查找位置;那么在已知了对象以后都有什么办法去快速查找对象的位置;(1)【无序查找】在前面的学习中,我们看到如果这些对象是无序的装在一个容器中(数组,顺序表,链表,普通二叉树)那么就拿着这个对象去容器中一个一个的找,如果找到了,就查到了该对象的位置,如果没有找到说明对象没在这个容器中;这种情况下的查找时间复杂度为O(N)(2)【全序查找】如果我们将原创 2017-08-08 01:40:06 · 672 阅读 · 0 评论 -
单链表排序问题(冒泡/快排【前后指针法】)
#include<iostream>#include<assert.h>using namespace std;typedef struct Node{ int data; struct Node* next; Node(int x) :data(x) ,next(NULL) {}}Node;----------//核心代码原创 2017-07-14 17:45:18 · 851 阅读 · 0 评论 -
二叉搜索树(BST树)
一、简介(1)二叉搜索树,又叫做二叉排序树,二叉查找树,有序二叉树 是指一棵空树或者具有下列性质的二叉树:每个节点都有一个作为搜索依据的关键码(key),所有节点的关键码互不相同。左子树上所有节点的关键码(key)都小于根节点的关键码(key)。右子树上所有节点的关键码(key)都大于根节点的关键码(key)。左右子树都是二叉搜索树。(2)二叉搜索树中序遍历的结果就是一个升序序列;(3)原创 2017-07-30 03:01:35 · 370 阅读 · 0 评论 -
红黑树【RBTree】
一、红黑树简介红黑树是一棵二叉搜索树,它在每个节点上增加了一个存储位来表示节点的颜色,可以是Red或Black。通过对任何一条从根到叶子简单路径上的颜色来约束,红黑树保证最长路径不超过最短路径的两倍,因而近似于平衡。红黑树是满足下面红黑性质的二叉搜索树 1. 每个节点,不是红色就是黑色的 2. 根节点是黑色的 3. 如果一个节点是红色的,则它的两个子节点是黑色的 4. 对每个节点,从该节点到原创 2017-09-06 17:34:58 · 387 阅读 · 0 评论 -
线索二叉树
一、简介二叉树是一种非线性结构,遍历二叉树几乎都是通过递归或者用栈辅助实现非递归的遍历。用二叉树作为存储结构时,取到一个节点,只能获取节点的左孩子和右孩子,不能直接得到节点的任一遍历序列的前驱或者后继。为了保存这种在遍历中需要的信息,我们利用二叉树中指向左右子树的空指针来存放节点的前驱和后继信息。那么这样的话就会将一个二叉树中所有的结点的指针域都利用起来;如果一个结点的左右指针有指向的左右孩子,则不原创 2017-08-28 21:35:52 · 497 阅读 · 0 评论 -
AVL树
一、AVL树简介(1)AVL树又称为高度平衡的二叉搜索树,是1962年有俄罗斯的数学家G.M.Adel’son-Vel’skii和E.M.Landis提出来的。 它能保持二叉树的高度平衡,尽量降低二叉树的高度,减少树的平均搜索长度;(2)AVL树是既满足二叉搜索树的性质,同时又满足平衡树的性质(左右子树的高度差不超过1)(3)AVL树的性质: 1>左子树和右子树的高度之差的绝对值不超过1 2>原创 2017-07-31 02:07:17 · 466 阅读 · 0 评论 -
TopK问题--100W个数种找出其中最大的前K个数;
一、100W个数种找出其中最大的前K个数—-建小堆 找最小–建大堆 ; 二、//100W个数种找出其中最大的前K个数;//知识回顾://bit---比特//Byte----字节//*1T=1024GB//1GB=1024MB//1MB=1024KB//1KB=1024B//1B=8原创 2017-08-15 02:24:36 · 1287 阅读 · 0 评论 -
【选择排序】和【堆排序】
一、选择排序(1)选择排序的算法思路(假设升序) 每次从待排序的区间中找到一个最小数,然后将这个最小数和该区间的第一个数交换数值;然后缩小区间,继续这样的的方法,最终到该待排区间为一个数时停止,排序完成;总体算法分三步完成:选数据—>将所选数据放入合适位置—>缩小需要排序的范围(2)图说 (3)程序#include<iostream>#include<assert.h>using nam原创 2017-07-13 18:57:47 · 263 阅读 · 0 评论 -
堆得应用【一】--【优先级队列priority_queue】
先看一下STL中优先级队列实现的功能: 一、介绍优先级队列优先级队列就是每次top可以取到队列的最值;每次pop都能删除队列中的最值; 那么我们应该如何实现呢?优先级队列是我们常见的数据结构队列的一种变形,对于队列,大家都很熟悉;就是先进如队列的元素,先出队列,那么一般的队列是可以尾插,可以头删,可以取到头部的元素,,可以到尾部取元素;我们要将一般队列实现优先级队列有三种方法: 方法一:就是我原创 2017-08-14 05:57:59 · 368 阅读 · 0 评论 -
Heap【堆】
1.堆得介绍堆得数据结构是一种数组对象,堆可以被看做一颗完全二叉树(借助二叉树的思想建堆以及插入和删除比较形象直观)2.堆得分类:①最大堆:每个父节点>它的孩子结点 ②最小堆:每个父节点<它的孩子结点3.堆得应用①优先级队列 ①堆排序 4.堆得底层是一个数组,学了STL库之后,可以将底层写层vector,可以动态增容5.堆得创建将一个数组中的元素进行向下调整,调成大堆或者小堆6.时间复杂度:建原创 2017-08-14 04:06:23 · 414 阅读 · 0 评论 -
【哈希表】+【位图】+【布隆过滤器】
总结原创 2017-08-12 02:44:37 · 389 阅读 · 0 评论 -
布隆过滤器【BloomFilter】
布隆过滤器(Bloom Filter)是1970年由布隆提出的。它实际上是一个很长的二进制向量和一系列随机映射函数。布隆过滤器可以用于检索一个元素是否在一个集合中。它的优点是空间效率和查询时间都远远超过一般的算法,缺点是有一定的误识别率和删除困难。布隆过滤器一般是用来判断字符串是否在一个集合中; 布隆过滤器的原理是开辟一个位数组用每一位来标记一个数是否存在;这个数就是字符串经过哈希函数映射来的ha原创 2017-08-12 01:49:09 · 446 阅读 · 1 评论 -
【位图】--利用位图储存大数据,节省空间,快速查找
#include<iostream>using namespace std;#include<vector>class BitMap{public: BitMap(size_t MaxNum)//构造函数 { _arr.resize((MaxNum>>5)+1); } void Set(size_t num)//位图中插入元素 {原创 2017-08-11 16:08:00 · 752 阅读 · 0 评论 -
c++实现单链表
一、用面向对象的思想,用c++语言实现单链表类(1)链表结点的定义typedef int DataType;struct ListNode{ ListNode(const DataType& x) :data(x) ,next(NULL) {} DataType data; ListNode* next;};(2)链表的成员变量原创 2017-05-28 13:36:06 · 1271 阅读 · 0 评论 -
链表面试题(十三)---求两个都不带环的链表相交的结点
一、结构体定义typedef int DataType;typedef struct ListNode//定义结点{ DataType data; struct ListNode* next;}ListNode,*PListNode;typedef struct PList//定义一个成员是指向结点的指针的结构体{ PListNode PHead;}PList,*P原创 2017-05-17 02:04:27 · 303 阅读 · 0 评论 -
稀疏矩阵的压缩储存,稀疏矩阵的普通转置,稀疏矩阵的快速转置
前言:什么是稀疏矩阵: 一个M*N(即M行N列)的矩阵,矩阵中有效值的个数远小于无效值的个数,且这些数据的分布没有规律。 例如:一个6行5列的稀疏矩阵(M = 6,N = 5) 1, 0, 3, 0, 5 0, 0, 0, 0, 0 0, 0, 0, 0, 0 1, 0, 3, 0, 5 0, 0, 0, 0, 0 0, 0, 0, 0, 0 一、稀疏矩阵的压缩储存原创 2017-04-18 23:27:48 · 1226 阅读 · 0 评论 -
二叉树面试题(二)---求一颗二叉树的镜像
一、二叉树的镜像就是一个树在镜子里的成像;好吧!初中的物理知识来了,哈哈,其实很简单,采用递归的方法求二叉树的镜像: (1)如果树为空,直接返回NULL; (2)如果树不为空,求其左子树和右子树的镜像,递归完成后,将左子树的镜像放在根结点的右边,将右子树的镜像放在根结点的左边; 二、图说 三:代码实现#include<iostream>using namespace std;#inc原创 2017-04-20 11:24:56 · 542 阅读 · 0 评论 -
二叉树面试题(一)---判断两个二叉树结构是否相同
一、首先这个问题是判断二叉树的结构是否相同,所以这就和二叉树的数据的值无关。只需要判断结构;判断两个二叉树的结构是否相同很简单。 采用递归的思想: (1)如果两棵二叉树都为空,返回真 (2)如果两棵二叉树一棵为空,另一棵不为空,返回假 (3)如果两棵二叉树都不为空,则递归判断其对应的左子树和右子树结构是否相同,如果都相同返回真,其他返回假 二、代码实现#include<iost原创 2017-04-19 23:17:59 · 9177 阅读 · 0 评论 -
单链表实现(C语言版,无头结点)
前言:单链表:它是一种链式储存的线性表,用一组地址任意的储存单元存放线性表的数据元素;称储存单元为一个结点;结点:值域+指针域 链表:二、代码实现(1)结点定义:typedef int DataType;typedef struct ListNode{ struct ListNode* next; DataType data;}Node,*PNode;typedef stru原创 2017-05-02 02:42:04 · 6438 阅读 · 0 评论 -
栈和队列面试题(三)---用两个队列实现一个栈
一:queue是一种”先进先出”的数据结构,他在对尾插入元素,在队头删除元素,他既可以取到自己的队头元素,也可以取到自己的队尾元素; stack是一种”先进后出”的数据结构,他对元素的插入和删除都是在栈顶完成的;他不可以取自己栈底的元素;只能去取自己栈顶的元素; 所以用两个队列实现一个栈,就是用队列”先进先出“的原则实现栈“先进后出”特点: 所以只要实现栈的插入,原创 2017-04-16 00:48:07 · 1975 阅读 · 0 评论 -
栈和队列面试题(一)---一个数组实现两个栈
一,用一个数组实现两个栈(先进后出),有以下几种方法: ①数组的奇数位置存储一个栈的元素,偶数位置存储另一个栈的元素; ②两个栈分别从数组的中间向两头增长; 数组的中间位置看做两个栈的栈底,压栈时栈顶指针分别向两边移动,当任何一边到达数组的起始位置或是数组尾部,则开始扩容 ③两个栈分别从数组的两头开始增长。 将数组的起始位置看作是第一个栈的栈底,将数组的尾部看作第二个栈的栈底, 压栈时,栈顶指针原创 2017-04-12 22:55:03 · 3241 阅读 · 0 评论 -
模拟实现queue
一:queue在头文件中声明。queue是一个适配器类,底层类默认为deque。 它不允许随机访问队列元素,甚至不允许遍历队列。 queue的特点是✔先进先出,可以将★元素添加到队尾,★查看队尾和★队首的元素的值,★检查元素数目和★测试队列是否为空。 二:代码实现:#include <iostream>using namespace std;#include原创 2017-04-13 00:41:15 · 584 阅读 · 0 评论 -
对称矩阵的压缩储存
一、存储矩阵用一个二维数组即可; 二、什么是对称矩阵: 设一个N*N的方阵A,A中任意元素Aij,当且仅当 Aij == Aji(0 <= i <= N-1&& 0 <= j <= N-1),则矩阵A是对称矩阵。以矩阵的对角线为分隔,分为上三 角和下三角 三、对称矩阵的压缩储存: 压缩存储称矩阵存储时只需要存储上三角/下三角的数据,所以最多存储n(n+1)/2个数据(相当于1+2+原创 2017-04-18 18:11:25 · 10408 阅读 · 0 评论 -
模拟实现stack
一、stack是一种序列式容器,他的特点是先进后出,只能在栈顶对元素进行压栈和出栈操作; 模拟是实现stack,要实现★栈的判空,★求栈中元素个数,★压栈和★出栈操作,★返回栈顶元素等; 二:程序代码:#include <iostream>using namespace std;#include <cassert>#include<cstdlib>template<class原创 2017-04-13 00:05:44 · 709 阅读 · 0 评论 -
非递归实现二叉树的前序,中序,后序遍历打印
前言:前面这篇文章主要是用递归的思想写了一颗二叉树,其中包括前序建树;前序,中序,后序遍历打印,层序遍历(非递归);求高度;求节点数;求叶子节点数;求第k层结点树等;详情请看: 递归实现二叉树的前,中,后序打印在我们了解了最简单的递归遍历以后,现在来说说用栈辅助,非递归实现二叉树的前序,中序,后序遍历打印 一:非递归实现前序遍历打印 1. 前序遍历,访问的顺序为根->左->右; 2. 前原创 2017-04-12 17:40:08 · 4749 阅读 · 0 评论 -
amp和set
1.map和set是两个主要的关联容器。2.关联容器和顺序容器的区别:(1)关联容器中的元素是按照关键字来保存和访问的;(2)顺序容器中的元素是按照它们在容器中的位置来顺序保存和访问的。 3.map和set的底层都是通过红黑树来实现的,即中序遍历得到的序列是关键字的升序排列。一.set (1)容器中只含有关键字,并且关键字不可以重复。通过以下代码,让我们来具体了解s原创 2017-02-16 13:42:00 · 312 阅读 · 0 评论 -
细说递归
程序调用自身的编程技巧称为递归( recursion)。递归做为一种算法在程序设计语言中广泛应用。 一个过程或函数在其定义或说明中有直接或间接调用自身的一种方法,它通常把一个大型复杂的问题层层转化为一个与原问题相似的规模较小的问题来求解,递归策略只需少量的程序就可描述出解题过程所需要的多次重复计算,大大地减少了程序的代码量。递归的能力在于用有限的语句来定义对象的无限集合。一般来说,递归需要有边原创 2017-03-21 23:31:15 · 260 阅读 · 0 评论