
数据结构
文章平均质量分 65
成长的菜鸟1018号
菜鸟一枚,希望早日脱离菜鸟
展开
-
【二叉树】二叉树的高度以及创建 销毁二叉树
更多的二叉树题 二叉树面试题二叉树的高度分析:求二叉树的高度,可以用递归的思想,先求出左子树的高度,再求出右子树的高度,然后取他们的最大值+1。int GetHight(Node *pRoot){ if(pRoot == NULL) return 0; if(pRoot->left == NULL || pRoot->right == NULL) return 1;原创 2017-07-23 13:15:49 · 768 阅读 · 0 评论 -
【链表】合并两个有序链表,合并后链表依旧有序
链表的结点结构struct Node{ Node(int value) :_value(value) , _next(NULL) {} int _value; Node* _next;};问题描述:输入两个递增排序的链表,合并这两个链表并使新链表中的结点仍然按照递增排序的。解决问题:方法一 递归版本Node* Merge(Node *pHead1,原创 2017-07-14 11:38:58 · 704 阅读 · 0 评论 -
【链表】反转/逆置 链表,以及升级版Node* RotateList(Node* list, size_t k)
问题描述:定义一个函数,输入一个链表的头结点,反转该链表并输出反转后链表的头结点。考虑:1只有一个结点。2、链表为空//思路:定义三个指针,改变链表结点的指向//考虑 1一个结点,没有及诶单Node *ReverseList(Node* pHead){ Node* ReverseHead = NULL; Node* pNode = pHead; Node* pPrev原创 2017-07-14 11:42:16 · 386 阅读 · 0 评论 -
【链表】查找链表倒数第k个结点,要求只能遍历一次
解决思路:定义两个指针,一个指针先走k步,然后同时走,当快的指针走到结尾是,慢的指针正好走到倒数第k个。注意:最后一个结点是倒数第0个考虑:结点个数小于k个,k<=0;头结点为空//查找链表的倒数第k个结点(最后一个是倒数第0个),要求只能遍历一次链表//思路:定义两个指针,一个先走k步,然后同时走到尾//考虑的问题:结点个数小于k个,k<=0;头结点为空Node* FindKtnToTail原创 2017-07-14 11:46:00 · 655 阅读 · 0 评论 -
【链表】判断链表是否有环,环的长度,环的入口点
问题描述:给出一个单链表的头结点,1、判断该链表是否有环;2、带环的话,求出环的长度,3、求出环的入口位置。1、判断是否带环,(求出环中相遇的点)分析:如果链表带环的话,那么遍历链表的话,就是一个死循环; 那么可以用追赶的方式,定义两个指针,一个走一步,另一个走两步,最终有环的话,两个指针指向同一个节点。注:如果带环的话,该函数返回的是环中相遇的点。//求环中相遇的节点Node* IsHaveC原创 2017-07-16 13:21:57 · 1010 阅读 · 0 评论 -
【链表】判断两个链表是否相交,并求出交点
问题描述:判断两个链表是否相交,并求出交点。简单分析:考虑到链表是否带环的问题,可分为3种情况,1、两个链表都不带环2、其中一个链表带环(根本就不可能相交)3、两个链表带环下面具体情况具体分析 注:判断链表是否带环,可以查看上一篇博客 判断链表是否带环1、两个链表都不带环分析情况:如果两个链表不带环且相交的话,有两种思路: 思路1、 遍历两个链表,如果相加相交的话,最终的结尾点是相等的。但原创 2017-07-16 16:54:33 · 702 阅读 · 0 评论 -
【链表】复杂链表的复制
问题描述请实现函数ComplexListNode* Clone(ComplexListNode* pHead),复制一个复杂链表。在复杂链表中,每个结点除了有一个next指针指向下一个结点之外,还有一个random指向链表中的任意结点或者NULL。结点的定义如下struct RandomListNode { int label; struct RandomListNode *next原创 2017-07-17 13:14:46 · 368 阅读 · 0 评论 -
【链表】删除一个无头单链表的非尾节点 以及从尾到头打印单链表
删除一个无头单链表的非尾节点分析:最直观的思路,删除一个节点,需要知道该节点的前一个节点,然后将该节点的前一个节点指向该节点的下一个节点。 思路:可将删除的节点的下一个节点 覆盖掉当前要删除的点,然后原删除的节点指向下一个节点的下一个节点。//确保posNode不是尾节点void DelNotTailNode(Node *posNode){ if (posNode) {原创 2017-07-17 13:23:55 · 374 阅读 · 0 评论 -
【链表】两个单链表求差集
问题描述已知集合A和B的元素分别用不含头结点的单链表存储,函数difference()用于求解集合A与B的差集,并将结果保存在集合A的单链表中。例如,若集合A={5,10,20,15,25,30},集合B={5,15,35,25},完成计算后A={10,20,30}。 链表结点的结构类型定义如下: struct node { int data; node* next; }; 请完成函数voi原创 2017-07-27 14:41:56 · 7701 阅读 · 2 评论 -
【二叉树】实现二叉树的前序、中序、后序的非递归遍历
二叉树的前序、中序、后序遍历的递归算法很好实现,这就不写了。非递归的实现肯定要借助栈来实现前序非递归的实现:根->左->右实现1、 借助栈的后进先出的思想,将根节点放入栈中,然后访问栈顶元素(根),然后将右孩子入栈,再将左孩子入栈,由于栈是后进先出,所以先出栈的是左孩子,这样就实现了先访问根,再访问左孩子,最后访问右孩子。void PreOreder_Nor(Node* pRoot){原创 2017-07-27 11:04:40 · 719 阅读 · 2 评论 -
【二叉树】层次遍历二叉树以及判断一棵树是否是完全二叉树
层次遍历二叉树分析:层次遍历二叉树也称广度优先遍历,是一层一层的遍历二叉树,可以借助队列,先进先出。 注:与前序遍历的非递归有点像,一个是栈,一个是队列void LevelOreder(Node *pRoot){ cout << "层次遍历 "<<endl; if(pRoot == NULL) return ; queue<Node *> q; q原创 2017-07-27 18:06:52 · 2280 阅读 · 0 评论 -
【树】求树中两个节点的最低公共祖先
求树中的两个节点的最低公共祖先,是一组题目,不同条件下的题目是完全不一样的。情形1、二叉搜索树分析:如果树是二叉搜索树的话,就比较容易解决。因为二叉搜索树的特性,左子树的上节点的值比根节点小,右子树上节点的值比根节点大。思路:从树的根节点开始和两个输入的节点进行比较。(1)如果当前节点的值比两个节点的值都大,最低公共祖先结点一定在当前结点的左子树。(2)如果当前节点的值比两个节点的值都小,最低公共祖原创 2017-07-27 21:11:36 · 1297 阅读 · 0 评论 -
【二叉树】由前序遍历和中序遍历重建二叉树
问题分析遍历组合确定唯一的二叉树,必须包含中序遍历 前序遍历和中序遍历重建二叉树, 前序遍历:根->左->右,中序遍历:左->根->右可以看出二叉树前序遍历序列中,第一个元素总是树的根节点的值。中序遍历序列中,左子树的节点的值位于根节点的值的左边,右子树的节点的值位于根节点的右边。思路:递归处理 (1)取前序遍历中的节点,在中序遍历中找到对应的值,划分为左右子树 (2) 构建根节点的左右子树原创 2017-07-28 10:45:37 · 646 阅读 · 0 评论 -
【二叉树】将二叉搜索树转换成一个排序的双向链表
问题描述输入一棵二叉搜索树,将该二叉搜索树转换程一个排序的双向链表。 要求不能创建任何新的节点,只能调整树中节点指针的指向。 也就是left当prev,right当next。–中序线索化的变型。 分析解决问题将上述二叉搜索树看成三个部分:值为10的根节点,值为6的左子树,值为14的右子树。 根据排序链表可以看出来,值为10的根节点的前序是它左子树中最大值为8的节点,后继是它右子树中最小值为12原创 2017-07-29 18:18:16 · 816 阅读 · 1 评论 -
【二叉树】二叉树后序线索化以及后序遍历
构建节点:多了双亲节点struct BinaryTreeNodeThd{ BinaryTreeNodeThd(const T& data) : _data(data) , _pLeft(NULL) , _pRight(NULL) , _pParent(NULL) , _LeftThread(LINK) , _RightThread(LINK) {} T _data; Bi原创 2017-02-18 17:00:32 · 6719 阅读 · 0 评论 -
二叉树的线索化以及 线索化的先序,中序,后序遍历
先简要说下什么线索化二叉树是一种非线性结构,遍历二叉树几乎都是通过递归或者用栈辅助实现非递归的遍历。用二叉树作为存储结构时,取到一个节点,只能获取节点的左孩子和右孩子,不能直接得到节点的任一遍历序列的前驱或者后继。由于有n个结点的二叉链表中必定存在n+1个空指针域,因此充分利用这些空指针域来存放结点的前驱和后继信息。本篇主要介绍二叉树的前序和中序线索化以及遍历,下篇介绍后序线索化以及遍原创 2017-02-18 20:03:01 · 2001 阅读 · 0 评论 -
二叉树的面试题(一)
二叉树面试题:1 创建二叉树2 前序 中序 后序遍历(递归和非递归)3 层序遍历4求二叉树的深度5求二叉树中叶子结点的个数6 求二叉树中节点的个数7求二叉树第k层的节点个数8 判断两棵二叉树是否结构相同原创 2017-03-18 17:41:21 · 866 阅读 · 0 评论 -
二叉树的面试题(二)
接着上篇博客接着讲述二叉树的面试题9 由前序遍历序列和中序遍历序列重建二叉树10 判断一个节点是否在二叉树中11 判断二叉树是不是平衡二叉树12 判断一颗二叉树是否为完全二叉树13 求二叉树的镜像14 将二叉查找树变为有序的双向链表原创 2017-03-18 17:44:21 · 609 阅读 · 0 评论 -
【字符串】模拟实现atoi和itoa
atoi 函数用来将字符串转化为数字的,C++手册上是这样描述的The function first discards as many whitespace characters as necessary until the first non-whitespace character is found. Then, starting from this character, takes an op原创 2017-08-06 13:48:08 · 609 阅读 · 0 评论 -
排序算法(一) 插入排序和希尔排序
本篇博客介绍的是排序算法(一) 插入排序:直接插入排序和希尔排序 插入排序的思想:在一个已排好序的记录子集的基础上,每一步将下一个待排序的记录语序插入到已排好序的记录子集中,直到将所有待排记录全部插入为止。一、直接插入排序 直接插入排序是一种最基本的插入排序方法,其基本操作是将第i个记录插入到前面i-1个已排好的记录中。 直接插入排序的思想:将第i个元素的关键字Ki,顺次与前面记录原创 2017-03-13 18:18:31 · 1025 阅读 · 0 评论 -
【二分查找】在排序数组中,找出给定数字的出现次数 以及二分其他应用
分析题目:数组是已排序好的,找出给定数字key出现的次数,方法1、最直观的方法就是遍历一遍数组,时间复杂度O(N)方法2、可以借助二分查找,时间复杂度为O(logN) 找出最左边出现的key出现的位置,找出最右边key出现的位置。size_t getLow(int *array,int size, int k){ size_t left = 0; size_t right = s原创 2017-09-07 22:15:09 · 1010 阅读 · 0 评论 -
【项目】哈夫曼树的应用:文件压缩
在前几天写了哈夫曼树以及哈夫曼编码的博客:http://blog.youkuaiyun.com/wenqiang1208/article/details/77261906文件压缩文件压缩的主要思想是利用哈夫曼编码来实现的,但是得到编码之前我们需要构建这棵树。那么利用什么来构建树呢?!这里,我们需要统计每个字符出现的次数,用次数来构建Huffman-Tree。假设我们现在有一个.txt的小文件,内容是”aaaab原创 2017-08-18 16:53:30 · 1900 阅读 · 1 评论 -
【栈队列】一个数组实现两个栈(共享栈)
一个数组实现两个栈,就是共享栈的实现问题。从图中可以看出,数组的起始位置和终点位置分别为两个栈的栈底。 给一个数组,给出两个栈顶,再给一个数组的容量。废话不说,代码实现template<class T>class SharedStack{public: SharedStack() : _a(NULL) , _top1(0) , _top原创 2017-08-15 16:59:10 · 1197 阅读 · 0 评论 -
【STL】队列的实现以及应用
队列的概念定义 队列:只允许在一端进行插入数据操作,在另一端进行删除数据操作 的特殊线性表。 进行插入操作的一端称为队尾,通常称为入队列;进行删除操作的一端称为队头,通常称为出队列。 队列具有先进先出的特性(FIFO)。顺序队列 顺序队列就是用数组实现的,定义两个变量front和rear指向队首和队尾实现方式一:队头固定在数组的起始位置,入队时队尾移动,出队时,将队尾到队首的元素向前移动一原创 2017-08-15 16:45:51 · 3474 阅读 · 2 评论 -
【STL】栈的实现原理以及应用
栈定义以及其他类型的栈栈又称堆栈,是一种运算受限的线性表,其限制是仅允许在表的一端进行插入和删除运算。把对栈进行运算的一端称为栈顶,另一端称为栈底。 向一个栈插入新元素称为入栈或进栈,Push;从一个栈删除元素称为退栈或出栈,Pop。因为后进栈的元素必定先出栈,所以又把栈称为后进先出表(Last In First Out, LIFO)。共享栈 共享栈是其实就是一个数组,从两边存放数据。链式栈原创 2017-08-15 15:22:59 · 9540 阅读 · 0 评论 -
【笔试题】拼多多2018校招内推编程
2、大数据相乘问题描述有两个用字符串表示的非常大的大整数,算出他们的乘积,也是用字符串表示。不能用系统自带的大整数类型。 输入描述: 空格分隔的两个字符串,代表输入的两个大整数输出描述: 输入的乘积,用字符串表问题分析感觉有点坑,在编译器上可以通过,牛客上通不过,还有这道题没有考虑很多问题,比如说符号问题,输入非法情况,所以,以后编程题,先做出来,再考虑其他问题。大数据相乘,就是字符串相乘,有两原创 2017-08-06 23:00:49 · 3677 阅读 · 2 评论 -
【大数据】大数据字符串的加减乘除
在日常计算中,一般来说,数据不会太大,即使再大long long 8个字节也够用,但是现在来说数据很大,一般的数据类型都表示不了,那么就用字符串来表示数据。那么就有字符串数据的加减乘除运算。基本结构BigData.h有两种成员变量; long long _value; string _strData;两种构造函数:字符串,int 构造函数已经处理过字符串,正数的字符串是,”+…….”,负数原创 2017-08-06 20:28:21 · 2076 阅读 · 0 评论 -
【布隆过滤器】实现一个简单的布隆过滤器
原理布隆过滤器(Bloom Filter)是1970年由布隆提出的。它实际上是一个很长的二进制向量和一系列随机映射函数。布隆过滤器可以用于检索一个元素是否在一个集合中。它的优点是空间效率和查询时间都远远超过一般的算法,缺点是有一定的误识别率和删除困难。Bloom Filter 是一种空间效率很高的随机数据结构,Bloom filter 可以看做是对 bit-map 的扩展, 它的原理是:当一个元素被原创 2017-08-06 14:27:40 · 1902 阅读 · 0 评论 -
【位图】STL中bitset的使用
在C++STL中提供了位图的库bitset类,下面记录一下bitset的使用template <size_t N> class bitset;//N: Number of bits to contain 构造函数(1)bitset ( );//空的,默认设置为0(2)bitset ( unsigned long val ); (3)参数可以使字符串,使用:// constructing bitse原创 2017-08-06 09:06:45 · 1060 阅读 · 0 评论 -
【STL】verctor的简单剖析以及各种函数的实现
概述vector其实和array数组挺像的,但是vector之所以存在的原因是: vector是动态空间,随着元素的增加,它的内部机制会自行扩建空间以容纳新的元素;而array是静态空间,一旦配置大小就不能改变了;vector的数据结构 vector有三个成员变量。 T* _start; //表示目前使用的空间头 T* _finish;//表示目前是的空间尾 T* _end原创 2017-08-13 17:40:44 · 673 阅读 · 0 评论 -
【位图】位图实现,处理大数据
定义位图法就是bitmap的缩写。所谓bitmap,就是用每一位来存放某种状态,适用于大规模数据,但数据状态又不是很多的情况。通常是用来判断某个数据存不存在的。例如,要判断一千万个人的状态,每个人只有两种状态:男人,女人,可以用0,1表示。那么就可以开一个int数组,一个int有32个位,就可以表示32个人。操作的时候可以使用位操作。位图实现unsigned int bit[N];在这个数组里面,可原创 2017-08-05 16:19:20 · 3843 阅读 · 0 评论 -
【字符串】删除小写字母字符串中重复字符
问题描述删除小写字母字符串中重复字符。如果可以,优先删除重复字符中排在比他小字符前面的字符。 比如,输入:bbcacdww;输出:bacdw 提示:暴力求解效率太低,考虑哈希思想。问题分析就是将原来字符串中的相同的删除一个,这个考虑是否需要额外的存储空间,实现1、空间复杂度为O(1)void RemoveSame(string& s){ int temp = s[0]; for (原创 2017-08-05 14:56:15 · 2454 阅读 · 3 评论 -
【字符串】旋转字符串(左旋或右旋k个字符)
问题描述将N个字符的数组,循环右移K位。时间复杂度O(N)。 比如原数组序列为abcd1234,要求变换成的数组序列为1234abcd,即循环右移了4位。问题分析方法1、暴力位移法,时间复杂度为O(m*n)下面是左旋的方法,void LeftShift1(char *str,size_t len, size_t n){ //n >len的情况 if (n == len || n原创 2017-08-05 14:26:40 · 1743 阅读 · 0 评论 -
【哈希查找】hashtable
哈希概述线性表,二叉搜索树、AVL树、B树中,元素在存储结构中的位置与元素的关键码之间不存在直接的对应关系。在数据结构中搜索一个元素需要进行一系列的关键码比较。搜索的效率取决于搜索过程进行的比较次数。理想的搜索方法是可以不经过任何比较,一次直接从表中得到要搜索的元素。如果构造一种存储结构,使元素的存储位置与它的关键码之间建立一个确定的对应函数关系Hash(),那么每个元素关键码与结构中的一个唯一的存原创 2017-08-19 17:01:48 · 2040 阅读 · 0 评论 -
求一个无序数组的中位数。
问题描述求一个无序数组的中位数。 如:{2,5,4,9,3,6,8,7,1}的中位数为5,{2,5,4,9,3,6,8,7,1,0}的中位数为4和5。 要求:不能使用排序,时间复杂度尽可能低。 提示:考虑堆或者快排思想解决方法1:堆思路1: 分析:将数据平均分配到最大堆和最小堆中,并且保证最小堆中的数据存放的数据都比最大堆中是数据大,那么此时最小堆堆顶的元素一定是中位数。 那么如何保证最小堆中原创 2017-08-04 23:13:05 · 4037 阅读 · 0 评论 -
【鸽巢排序】对数组排序,要求时间复杂为O(n)
问题描述int a[] = {12,13,12,13,19,18,15,12,15,16,17},要求对数组a进行排序,要求时间复杂度为O(N) 。分析问题就已知的算法中,最小的时间见复杂度为O(N lgN):堆排序,快排,归并排序。题目中的数组元素中的数据范围比较小,最小为12,最大为17。可以考虑鸽巢排序 (1)找出排序数组中数据的范围,创建计数的数组count (2)遍历数组,存放到cou原创 2017-08-04 21:07:32 · 525 阅读 · 0 评论 -
shell脚本编写希尔排序
用shell脚本一些希尔排序#!/bin/bash#希尔排序function shell_sort(){ #获取参数,数组 echo "输入数组长度:" read size for((i = 0; i < size; ++i)) do echo "输入第$((i))个元素:" read array[i] done原创 2017-08-04 20:37:29 · 333 阅读 · 0 评论 -
求二叉树中两个节点的最低公共祖先节点
本篇博客接着写二叉树的面试题中:二叉树面试题(一) 二叉树面试题(二) 求树中两个节点的最低公共祖先节点这个题可能有几种不同的条件,那这样就是不同的问题(1) 树是二叉树,且是二叉搜索树。思路:如果是二叉搜索树,二叉搜索树是排序过的,位于左子树的节点都比父节点小,位于右子树的节点都比父节点大。我们只需要从树的根节点开始和两个输入的节点进行比较。如果当前节点的值比两个节点的值都原创 2017-03-21 16:00:32 · 5069 阅读 · 1 评论 -
【二叉树】判断一棵二叉树是否是平衡二叉树/求一棵二叉树的镜像/对称的二叉树
求一颗二叉树的镜像分析问题 镜像就是相反的东西,对于二叉树而言,将左子树改成右子树,右子树改成左子树。 递归实现1 可以采用递归的思路,前序遍历 依次交换当前根节点的左右孩子,再分别求左右子树镜像。 注:该方法改变了原来的树的结构void Mirror(Node *pRoot){ if(pRoot == NULL) return ; if(pRoot->l原创 2017-07-27 13:38:42 · 421 阅读 · 0 评论 -
【二叉树】树的子结构/判断一个节点是否在二叉树中
树的子结构问题分析 输入两棵二叉树A和B,判断B是不是A的子结构思路: 1、在树A中找到和B根节点值一样的节点R 2、再判断树A中以R节点为根节点的子树是不是包含和树B一样的结构。代码实现//步骤1,找一样的节点bool HasSubTree(TreeNode* pRoot1, TreeNode * pRoot2){ bool res = false; if (pRoot1原创 2017-07-27 15:40:46 · 1870 阅读 · 1 评论