数据结构
文章平均质量分 70
景亍
这个作者很懒,什么都没留下…
展开
-
剑指offer 7---使用两个栈实现一个队列
栈:先进后出队列:先进先出首先构建栈q1,q2。入队列:入栈q1。出队列:首先将q1中的所有元素依次压入q2中,此时q1为空,q2中存放所有数据,在依次将q2中数据pop,即实现队列。代码实现如下:#include #include #include #include using namespace std;template class Queue{原创 2017-05-03 20:41:48 · 854 阅读 · 5 评论 -
剑指offer 21---实现一个栈, 要求实现Push( 出栈) 、 Pop( 入栈) 、 Min( 返回最小值的操作) 的时间复杂度为O(1)
栈:先进后出实现方法:利用栈的性质,首先建立q1,q2两个栈,两个栈均为空。1.插入数据时,第一个数据在q1,q2中均插入。2.后面的数据依次插入q1中,每次插入一个数据后均和q2中的栈顶比较,如果此时数据大于s2的栈顶,则该数据不插入q2 中,如果此时数据小于或等于此时q2的栈顶,则将该数 据插入s2,依次进行。3.当所有数据入栈完毕后,s2的栈顶存储的即为该原创 2017-05-03 23:23:20 · 1200 阅读 · 3 评论 -
剑指offer 48---设计一个类不能被继承
设计一个类不能被继承在C++继承中,子类的构造函数会自动调用父类的构造,子类的析构会自动调用父类的析构。一个简单的例子:class AA{public: AA() { cout << "AA()" << endl; } ~AA() { cout << "~AA()" << endl; }};class BB:public AA{public: BB(原创 2017-07-17 13:27:51 · 619 阅读 · 0 评论 -
剑指offer27---将二叉搜索树转换成一个排序的双向链表
将二叉搜索树转换成一个排序的双向链表。要求不能创建任何新的结点,只能调整树中结点指针的指向。定义: 二叉搜索树也叫二叉查找树或二叉排序树,它可以是一颗空树,或者是满足如下性质的二叉树:若该树的左子树不为空,则左子树上所有节点的值均小于根节点的值,若该树的右子树不为空,则右子树上所有节点的值均大于根节点的值。实现: 二叉搜索树具有二叉树的基本性质,有两个指针分别指向它的左右孩原创 2017-05-25 21:14:00 · 848 阅读 · 0 评论 -
求二叉树叶子节点的个数 && 求第K层的节点个数
求二叉树叶子节点的个数思路:1.如果根节点为NULL时,则是空树,返回0;2.根节点不为空时,如果根节点的左右子树均为空,则该二叉树中只有一个节点,即返回1;3.叶子节点的个数=左子树叶子节点数+右子树叶子节点数;int _GetNodeyezi(Node* root) //叶子节点的个数 { if (root == NULL) { return 0;原创 2017-07-23 20:11:02 · 1390 阅读 · 0 评论 -
剑指offer 39---求二叉树的深度 && 输入一颗二叉树的根节点,判断该树是不是平衡二叉树
求二叉树的深度递归求解/*struct TreeNode { int val; struct TreeNode *left; struct TreeNode *right; TreeNode(int x) : val(x), left(NULL), right(NULL) { }};*/class Solution {public: int TreeDe原创 2017-07-23 21:46:16 · 780 阅读 · 0 评论 -
剑指offer 19---二叉树的镜像
二叉树的镜像 :镜像即就是在镜子中所成的像代码实现:PS:搜索二叉树和普通二叉树实现方法是相同的,只是两种建树过程有所不同,此处实现的是搜索二叉树。1.递归实现:#pragma once#include #include #include using namespace std;template struct SearchBinaryTreeNode原创 2017-05-25 15:30:25 · 460 阅读 · 0 评论 -
快速排序
快速排序基本思想: 通过一趟排序将要排序的数据分割成独立的两部分,其中一部分的所有数据都比另外一部分的所有数据小,然后,依次按此方法分割排序,以此达到整个数据变成有序序列。时间复杂度: O(N*logN) (最坏情况为O(N^2),即为每次选取的key值均为最大或最小;最优情况为O(N*logN),因为对于快排来原创 2017-05-17 15:25:47 · 667 阅读 · 0 评论 -
剑指offer 7---使用两个队列实现一个栈
队列:先进先出栈:先进后出首先构建队列q1,q2。入栈:入队列q1。出栈:将q1队列中的前n-1个元素倒入到q2中,在pop q1中的第n个元素,即为要出栈的元素,下次,则对q2操作,每次保证有一个队列为空。栈顶:将q1中前n-1个元素倒入q2中之后,第n个元素即为栈顶。考虑到我们取栈顶元素的便利性,我们在实现时使得栈顶等于队列头;由于栈的pop弹出栈顶元素,而队列的p原创 2017-05-03 17:24:10 · 1126 阅读 · 1 评论 -
剑指offer 22---判断元素出栈、 入栈顺序的合法性
题目:判断元素出栈、 入栈顺序的合法性。 如: 入栈的序列(1,2,3,4,5) , 出栈序列为(4,5,3,2,1) 是合法序列, 入栈的序列(1,2,3,4,5) , 出栈序列为(1,5,3,2,4) 是不合法序列。代码实现如下:#include #include #include #include using namespace std;//判断原创 2017-05-12 13:32:41 · 843 阅读 · 0 评论 -
冒泡排序
冒泡排序算法原理: 冒泡排序是交换排序的一种,是一种较简单的排序算法,它重复的走访要排序的数组,一次比较两个元素,如果顺序错误就交换,直到没有要交换的,算法终止。步骤: 1.比较相邻元素,如果第一个比第二个大,就交换(从小到大排)。 2.对每一对相邻元素作同样工作,依次比较。 3.针对所有元素重复以上步骤,原创 2017-05-13 20:04:13 · 1063 阅读 · 0 评论 -
直接插入排序
直接插入排序: 直接插入排序是一种简单的插入排序,比较适合用于少量的数据排序。ps: 我在这里先实现的是直接插入排序,上述代码之后会一 一实现。基本思想: 把一组需要排序的数据逐个,依次插入到一个已经排好序的有序队列中,每次一个个插入,从最后开始, 依原创 2017-05-08 19:57:22 · 992 阅读 · 0 评论 -
文件压缩(哈夫曼树实现)
项目描述:项目简介:利用哈夫曼编码的方式对文件进行压缩,并且对压缩文件可以解压开发环境:windows vs2013项目概述: 1.压缩 a.读取文件,将每个字符,该字符出现的次数和权值构成哈夫曼树 b.哈夫曼树是利用小堆构成,字符出现次数少的节点指针存在堆顶,出现次数多的在堆底 c.每次取原创 2017-04-18 18:16:02 · 1758 阅读 · 0 评论 -
bit_set(位图)
位图:位图就是bitset的缩写。所谓bitset,就是用每一位来存放某种状态,适用于大规模数据,但数据状态又不是很多的情况。通常是用来快速判断某个数是否存在。在STL中有一个bitset容器,其实就是位图法。位图法的优点:1.时间复杂度为O(1),可以快速判断数据是否存在。2.适用于处理大数据问题,节省空间。位图法的缺点:1.可读性差,每个bit只能存放1原创 2017-04-25 12:23:47 · 1636 阅读 · 1 评论 -
判断一个值是否在一棵二叉树中。(注意多测几个值,看是否都能找到)
判断一个节点是否在一棵二叉树中。(注意多测几个节点,看是否都能找到)思路:分别和二叉树中的每个结点值相比,找到返回true,找不到返回false//判断一个节点是否在一棵二叉树中。(注意多测几个节点,看是否都能找到) bool _IsExit(Node* root,T key) { if (root == NULL) { return false; } if原创 2017-07-27 11:20:37 · 1347 阅读 · 0 评论 -
实现二叉树的前序/中序/后序递归、非递归遍历
实现二叉树的前序/中序/后序非递归、递归遍历原创 2017-07-26 22:44:11 · 1171 阅读 · 0 评论 -
求一个无序数组的中位数
求一个无序数组的中位数中位数是将数组排序之后,数组个数为奇数时,取中间的即为中位数;数组个数为偶数时,取中间两个的平均值即为中位数。思路一:要取得中位数,即给数组排序,使用任意排序算法均可,然后按数组下标取其中位数。PS:该方法很直观,此处不实现思路二:1.设数组元素为n个,且为奇数个时,取数组前(n+1)/2个元素建一个小堆2.遍历数组剩余元素,如果比堆顶原创 2017-08-03 17:33:07 · 9662 阅读 · 3 评论 -
归并排序
归并排序:归并排序是建立在归并操作上的一种有效的排序算法,该算法是采用分治法的一个非常典型的应用。步骤:1.申请空间,使其大小为两个已经排序序列之和,该空间用来存放合并后的序列2.时间复杂度: O(N*lgN)空间复杂度: O(N) 需要额外空间性能: 稳定归并排序主要分原创 2017-08-03 12:50:15 · 453 阅读 · 0 评论 -
销毁一颗二叉树-->Destroy(Node* root)
销毁一颗二叉树-->Destroy(Node* root)二叉树的很多问题都可用递归实现//销毁一颗二叉树-->Destroy(Node* root) void _Destory(Node* root) { if (root != NULL) { _Destory(root->_left); _Destory(root->_right); delete ro原创 2017-07-23 22:04:33 · 4739 阅读 · 0 评论 -
剑指offer 18---输入两棵二叉树A和B,判断B是不是A的子结构
输入两棵二叉树A和B,判断B是不是A的子结构思路:1.先在A中找和B的根节点相同的结点2.找到之后遍历对应位置的其他结点,直到B中结点遍历完,都相同时,则B是A的子树3.对应位置的结点不相同时,退出继续在A中寻找和B的根节点相同的结点,重复步骤,直到有任何一棵二叉树为空退出/*struct TreeNode { int val; struct Tr原创 2017-07-23 17:36:34 · 1813 阅读 · 0 评论 -
并查集
并查集: 在一些有N个元素的集合应用问题中,我们通常是在开始时让每个元素构成一个单元素的集合,然后按一定顺序将属于同一组的元素所在的集合合并,期间要反复查找一个元素在哪个集合中。这一类问题近几年来反复出现在信息学的国际国内赛题中,其特点是看似并不复杂,但数据量极大,若用正常的数据结构来描述的话,往往在空间上过大,计算机无法承受;即使在空间上勉强通过,运行的时间复杂度也极高,原创 2017-05-25 13:16:48 · 472 阅读 · 0 评论 -
AVLTree
AVL树又称为高度平衡的二叉搜索树,是1962年有俄罗斯的数学家G.M.Adel'son-Vel'skii和E.M.Landis提出来的。它能保持二叉树的高度平衡,尽量降低二叉树的高度,减少树的平均搜索长度。AVL树的性质:1. 左子树和右子树的高度之差的绝对值不超过1。2. 树中的每个左子树和右子树都是AVL树。3. 每个节点都有一个平衡因子(balance factor--bf原创 2017-04-21 12:22:15 · 856 阅读 · 0 评论 -
一个数组实现两个栈
用一个数组实现两个栈方案一:奇偶下标依次存储 将数组下标为0的位置作为第一个栈的栈底,下标为1的位置作为第二个栈的栈底,将整个数组中偶数下标部分依次存储在第一个栈中,将数组中奇数下标部分依次存储在第二个栈中。 方案二:从中间分别向两边压栈 将数组的中间位置看做两个栈的栈底,压栈时栈顶分别向两边移动,当任何一边到达数组的起始位置或是数组的原创 2017-05-11 13:49:53 · 1111 阅读 · 2 评论 -
红黑树
红黑树是一棵二叉搜索树,它在每个节点上增加了一个存储位来表示节点的颜色,可以是Red或Black。通过对任何一条从根到叶子简单路径上的颜色来约束,红黑树保证最长路径不超过最短路径的两倍,因而近似于平衡。红黑树是满足下面红黑性质的二叉搜索树1. 每个节点,不是红色就是黑色的2. 根节点是黑色的3. 如果一个节点是红色的,则它的两个子节点是黑色的4. 对每个节点,从该节原创 2017-04-19 21:08:47 · 619 阅读 · 0 评论 -
大小堆实现
#include #include #include #include using namespace std;template class Heap{protected: vector _a; //一维数组 //void _AdjustDown(int root) //下调,构建大堆 //{ // int parent = root; // i原创 2017-03-24 16:48:28 · 395 阅读 · 0 评论 -
选择排序
选择排序原理: 每次遍历在数据元素中选出最大或最小的一个元素,放到合适位置,不断遍历,直到全部数据排序完成。性能: 选择排序是不稳定算法。时间复杂度: O(N^2)空间复杂度: O(1)缺点: 选择排序在任何情况下,无论需要待排序的序列是否有序,时间复杂度均为O(N^2),所原创 2017-05-15 17:29:28 · 838 阅读 · 0 评论 -
希尔排序算法
希尔排序算法定义: 希尔排序是插入排序的一种,也称缩小增量排序,是直接插入排序算法的一种更高效的改进版本。算法思想: 希尔排序是把记录按下标的一定增量分组,对每组使用直接插入排序算法排序,随着增量逐渐减少,每组包含的关键词越来越多,当增量减至1时,整个文件恰好被分为一组,算法终止。 时间复杂度: O(N)原创 2017-05-12 15:49:24 · 1274 阅读 · 1 评论 -
剑指offer 6---由前序遍历和中序遍历重建二叉树
由前序遍历和中序遍历重建二叉树思路分析: 代码实现:#include #include #include using namespace std;template struct BinaryTreeNode{ T _data; //节点的值 BinaryTreeNode* _left; BinaryTreeNode* _rig原创 2017-05-19 15:28:38 · 827 阅读 · 0 评论 -
剑指offer 37---求两个链表的第一个公共结点
求两个链表的第一个公共结点思路:此处求解的是两个单链表,如果两个单向链表有公共的结点,那么这两个链表从某一结点开始,它们的_next都指向同一结点。由于是单链表的结点,每个结点只有一个_next,因此从第一个公共结点开始,之后它们所有的结点都是重合的,不可能再出现分叉。所以两个有公共结点而部分重合的链表,拓扑形状像一个Y,而不可能是Xstruct ListNode{原创 2017-07-22 21:45:39 · 671 阅读 · 0 评论 -
剑指offer 17---合并两个排序的链表
一.链表1:1 3 5 7 9 链表2:2 4 6 8 10 升序排列#include #include using namespace std;//合并两个有序链表,假设链表是升序排列//链表1:1,3,5,7,9 链表2:2,4,6,8,10struct ListNode{ int _value; ListNode* _next; ListNo原创 2017-07-13 15:56:34 · 445 阅读 · 0 评论 -
剑指offer 15---查找单链表的倒数第k个节点,要求只能遍历一次链表
查找单链表的倒数第k个节点,要求只能遍历一次链表#include #include using namespace std;struct ListNode{ int _value; ListNode* _next; ListNode(const int& value) :_value(value) , _next(NULL) {}};//查找单链表的倒数第K个结原创 2017-07-14 14:30:44 · 808 阅读 · 0 评论 -
剑指offer 23----二叉树的前序、中序、后序、层序遍历
二叉树的前序、中序、后序、层序遍历#include #include #include using namespace std;templatestruct BinaryTreeNode //构建二叉树的节点,及左右子树的指针{ T _data; //值 BinaryTreeNode* _left; //左子树 BinaryTreeNode* _right原创 2017-07-21 14:20:21 · 620 阅读 · 4 评论 -
二叉树搜索 递归
#include #include using namespace std;template struct SearchBinaryTreeNode{ SearchBinaryTreeNode* _left; SearchBinaryTreeNode* _right; K _key; //关键码 SearchBinaryTreeNode(const K& key)原创 2017-04-07 08:11:04 · 547 阅读 · 0 评论 -
判断一棵二叉树是否是完全二叉树
判断一棵二叉树是否是完全二叉树定义: 完全二叉树就是除最后一层外,每一层上的节点数均达到最大值,在最后一层上只缺少右边的若干节点。 满二叉树是特殊的完全二叉树。如图:这些均为完全二叉树: 这个为满二叉树这些均为不完全二叉树:解题思路:1.原创 2017-05-22 13:46:26 · 990 阅读 · 0 评论 -
计数排序
计数排序 计数排序是一种非比较的排序算法优势: 计数排序在对于一定范围内的整数排序时,时间复杂度为O(N+K) (K为整数在范围)快于任何比较排序算法,因为基于比较的排序时间复杂度在理论上的上下限是O(N*log(N))。缺点: 计数排序是一种牺牲空间换取时间的做法,并且当K足够大时O(K)>O(N*lo原创 2017-05-26 13:54:19 · 688 阅读 · 0 评论 -
堆排序
堆排序定义: 堆排序是指利用heap这种数据结构所设计的一种排序算法,是选择排序的一种。可以利用数组的特点快速定位指定索引的元素,是完全二叉树。分类: 堆分为大堆和小堆,大堆要求每个节点的值均不大于其父节点的值,小堆要求每个节点的值均不小于其父节点的值。性能: 堆排序是不稳定的排序算法。(排序的稳定原创 2017-05-09 22:33:52 · 1380 阅读 · 3 评论