数据结构与算法
文章平均质量分 81
zhoujian_Liu
成为更好的我
展开
-
玩转数据结构(一)封装自己的动态数组
数组这个数据结构对我们来说都不陌生,所谓数组就是内存中一段连续的存储空间,可以用来存放同一种数据类型。数组可以通过索引快速进行查找,根据索引查找的时间复杂度是O(1);但是进行删除某一项时,往往要伴随着大量数据的移动操作,因此时间复杂度是O(n),但是在删除尾部元素时,就不用移动数据,时间复杂度为0(1)。由此可见,数组比较适合做查询。 这节将封装一个自己的数组,并且实现了在空间不够...原创 2018-07-03 17:06:07 · 497 阅读 · 0 评论 -
玩转数据结构(十四)如何实现set
1、set简介set是一种不支持重复元素的集合。本节将介绍两种实现set的方式,一种是基于BST实现,另一种基于链表实现。关于BST如何实现:构建BST关于LinkedList如何实现:实现LinkedList2、set接口public interface Set<E> { void add(E e); boolean contains(E e); void r...原创 2018-07-07 10:03:00 · 865 阅读 · 0 评论 -
玩转数据结构(十三)构建BST
1、二分搜索树简介二分搜索树又称为二叉搜索树、排序二叉树等,是指一棵空树或者具有以下性质的二叉树:若任意一个结点的左子树不为空,则左子树所有结点的值均小于它的根结点的值若任意一个结点的右子树不为空,则右子树所有结点的值均大于它的根结点的值任意结点的左右子树分别也为二分搜索树没有数值相等的结点二分搜索树是一种基本的数据结构,可以用来构建更为抽象的数据结构,如:set、map等。二分搜索树和其他数据结...原创 2018-07-07 09:27:46 · 1301 阅读 · 0 评论 -
玩转数据结构(十二)括号匹配算法
/** * 基于栈实现--括号匹配算法 */public class BracketMarch { ArrayStack<Character> stack = new ArrayStack<Character>(); public boolean isValid(String s) { for (int i = 0; i < s...原创 2018-07-04 16:39:18 · 2303 阅读 · 0 评论 -
玩转数据结构(十一)两个队列实现栈
1、思路分析现在有两个队列,queue1和queue2; 当要实现入栈操作时,将数据放入到不为空的队列中,要是两个队列都为空,默认先放入queue1队列中。如下图:a、b、c、d都放入到queue1队列中。当要实现出栈操作时,将不为空的队列中的数据放入到另一个为空的队列中,直至剩下一个;而那一个数据就是要出队的数据。如下图:将queue1中的a、b、c依次转移到queue2中,只剩下d,而d就是要...原创 2018-07-04 12:11:24 · 285 阅读 · 0 评论 -
玩转数据结构(十)两个栈实现队列
栈是一种先进后出的数据结构,而队列是一种先进先出的数据结构,如何使用两个栈实现一个队列呢?这也是面试中常问的问题。1、思路分析先来看一幅图:左侧描述的是使用两个栈实现入队操作:有两个栈stack1和stack2,将入队的数据全部压入stack1栈中,即可完成入队操作。右图描述的是使用两个栈实现出队操作:先判断stack2是否为空,要是为空,先将stack1中的数据全部压入stack2中,再弹sta...原创 2018-07-04 11:33:01 · 277 阅读 · 0 评论 -
玩转数据结构(九)数组队列、链式队列、循环队列性能测试
在前几篇博客中,分别基于动态数组实现了队列、基于链表实现了队列、基于数组实现了循环队列。这次分别对这几种队列进行性能测试。1、测试代码传递的参数为队列、操作次数。 private static double testQueue(Queue<Integer> q, int opCnt) { long start = System.nanoTime(); R...原创 2018-07-04 10:54:48 · 522 阅读 · 0 评论 -
玩转数据结构(八)循环队列
1、为什么要循环队列?可以看看这篇文章:静态队列为什么必须是循环队列2、循环队列要点 判空队列为空的条件:head == tail 判断队列已满的条件: (head + 1) % 数组长度 == tail 入队后维护tail: tail = (tail + 1) % 数组长度 出队后维护front: front = (front + 1)...原创 2018-07-03 21:06:16 · 271 阅读 · 0 评论 -
玩转数据结构(七)基于链表的队列
基于链表实现的队列,需要三个元素:头指针head、尾指针tail、计数的size。1、实现的Queue<E>接口public interface Queue<E> { int getSize(); void enqueue(E e); E dequeue(); E getFront(); boolean isEmpty();}2、...原创 2018-07-03 20:12:03 · 225 阅读 · 0 评论 -
玩转数据结构(六)基于动态数组的队列
队列是先进先出的线性表。在具体应用中通常使用链表或者数组来实现。队列只允许在后端进行入队操作(enqueue),在前端进行出队操作(dequeue)。如下图示例:<图片来源于百度>下面我们基于数组实现一个队列。数组对象在之前的博客中已经讲过:封装自己的Array对象1、队列接口public interface Queue<E> { int getSize(); ...原创 2018-07-03 19:52:19 · 327 阅读 · 0 评论 -
玩转数据结构(五)数组栈和链表栈性能对比
在之前的博客中,分别实现了基于数组的栈和基于链表的栈。下面来使用代码对比我们自己实现的栈的性能差异: private static double testStack(Stack<Integer> s, int opCnt) { long startTime = System.nanoTime(); for (int i = 0; i < opCn...原创 2018-07-03 19:24:26 · 1800 阅读 · 0 评论 -
玩转数据结构(四)基于链表实现栈
之前的博客中底层使用数组实现了栈,这次就使用链表来实现栈。链表在上一篇博客中已经实现好了,实现栈只要复用上次博客中实现的LinkedList即可。资源跳转:玩转数据结构-实现自己的链表LinkedList1、栈接口public interface Stack<E> { int getSize(); void push(E e); E pop(); E p...原创 2018-07-03 18:11:44 · 238 阅读 · 0 评论 -
玩转数据结构(三)实现链表LinkedList
链表是一种线性数据结构,是由一个个节点构成,节点之间由指针(引用)连接起来;凡是谈到链表就要和数组来做比较。那来比较一下数组和链表的区别:数组要求的内存连续,而链表不需要数组的增删比较复杂,需要涉及数组元素的移动操作,而链表的增删只需要更改指针的指向即可数组按照索引查询的时间复杂度为O(1),而链表查找一个元素时需要从头结点开始遍历查找数组存储内容没有浪费额外空间,而链表花费空间存储了指针(引用)...原创 2018-07-03 17:59:45 · 362 阅读 · 0 评论 -
玩转数据结构(二)基于动态数组实现的栈
栈是一种先进后出的数据结构。在计算机中有好多处用到栈,例如:文本编译器中的undo操作、计算机系统中的递归调用、JVM中方法的执行中、括号匹配算法等都会用到栈这种数据结构。在这次博客中,使用上次封装的Array数组来实现自己的栈。资源跳转:玩转数据结构>封装自己的Array数组1、栈的接口public interface Stack<E> { int getSize();...原创 2018-07-03 17:26:22 · 280 阅读 · 0 评论 -
玩转数据结构(十五)如何实现Map
Map是一个存储key-value键值对的数据结构,这篇博客将会使用BST和linkedList分别实现一个自己的Map。0、Map接口public interface Map<K, V> { void add(K key, V value); V remove(K key); boolean contains(K key); V get(K key);...原创 2018-07-07 10:30:54 · 723 阅读 · 0 评论