数据结构和算法分析 表、栈和队列

表是ArrayList,LinkedList,Stack,Queue的抽象定义。我理解为有序的单数据存储。

remove方法对LinkedList类的使用

模拟一个场景,遍历一个LinkedList,将其中存储的数值是偶数的都删除。

  • 方法一:通过下标i进行for循环,如果发现是偶数,然后使用remove(i)进行删除。这种方法的时间复杂度是O(N2),因为外层遍历的复杂度是N,内存要进行get(i)和remove(i)他们的复杂度都是N。
  • 方法二:使用增强for循环,会产生异常:增强for循环在循环的过程中,使用iterator,但是由于没有在iterator中使用remove,而是使用list.remove方法,这种是不会被iterator识别到的。所以有如下要求:增强型的for循环过程中,不能删除数据。
  • 方法三:使用iterator。iterator.hashNext, iterator.next, iterator.remove,因为iterator在remove的时候,已经定位到了要删除的链表元素位置,所以删除操作的复杂度为O(1),整个实现的时间复杂度为O(N)。

ListIterator

ListIterator在Iterator(hasNext,next,remove)的基础上增加了hasPrevious,previous,add,set方法。

ArrayList的iterator方法返回一个ListIterator对象,是通过内部类来实现的。整个private的私有(非static)内部类可以访问外部类的数组和size等属性,可以简单的实现,next,hashnext等各种操作。

java的LinkedList是双向链表实现。在做get(i)操作的时候,会判断i和size/2的比较,然后选择从head还是tail开始进行遍历。

 

java集合库中设计的栈没有接口,就是一个Stack类,而且它继承自Vector类,是使用监视器锁实现的。比较重量级。如下是Stack的反编译后的代码:

如果不想使用这么重量级的,可以使用ArrayList和LinkedList模拟Stack的操作,或者使用Deque接口来模拟也可以。

如果要自定义一个Stack类,可以通过数组和链表来实现。

简单是数组实现:

  1. package com.zjf;
  2.  
  3. public class MyArrayStack<E> {
  4.  
  5.    public final static int initSize = 32;
  6.    private Object[] arr;
  7.    private int top = 0;
  8.  
  9.    public static void main(String[] args) {
  10.       // TODO Auto-generated method stub
  11.  
  12.    }
  13.  
  14.    public MyArrayStack() {
  15.       arr = new Object[initSize];
  16.    }
  17.  
  18.    public void push(E element) {
  19.       if ((top + 1) >= initSize) {
  20.          resizeArray();
  21.       }
  22.       arr[top] = element;
  23.       top++;
  24.    }
  25.  
  26.    public E pop() {
  27.       if (top == 0) {
  28.          throw new RuntimeException("没有数据");
  29.       }
  30.       E element = (E) arr[top];
  31.       top--;
  32.       return element;
  33.    }
  34.  
  35.    // 如果超出空间
  36.    private void resizeArray() {
  37.  
  38.    }
  39.  
  40. }

栈的应用:

平衡符号:编译器检查程序的语法错误。

表达式求值:用于计算中:中缀表达式向后缀表达式的转换。

队列

队列的数组实现,我的大概思路:

使用循环数组,维护int变量head和tail,标识头尾,arr数组用来存储数据,插入到++tail位置,取出从head—中取。如果插入到了数组最后一个,空间不足,那么从0开始循环(要判断head的位置 如果空间不足就要扩充)。

 

posted on 2017-07-09 12:45  张小贱1987  阅读(153)  评论(0编辑  收藏  举报

导航