Loading

数据结构 第3章 笔记与总结

3.1 抽象数据类型 abstract data type

ADT = 数据结构 + 操作

3.2 表ADT

3.2.1 表的简单数组实现

数组 arr 在必要时候被扩展

1 int[] arr = new int[10];
2 ...
3 // 扩大arr
4 int[] newArr = new int[arr.length * 2];
5 for(int i = 0; i < arr.length; i++)
6     newArr[i] = arr[i];
7 arr = newArr;

 

3.2.2 简单链表

3.3 Java Collections API 中的表

3.3.1 Collections 接口

Collections API位于java.util包中。集合的概念在Collections接口中得到抽象,它存储一组类型相同的对象。下面显示该接口一些最重要的部分(一些方法未被显示)

 1 public interface Collections<AnyType> extends Iterable<AnyType> 
 2 {  
 3   int size();
 4     boolean isEmpty();
 5     void clear();
 6     boolean contains(AnyType x);
 7     boolean add(AnyType x);
 8     boolean remove(AnyType x);
 9     java.util.Iterator<AnyType> iterator();
10 }

Collection接口继承了Iterable接口。实现了Iterable接口的类可以拥有增强的for循环。如下:

1 public static<AnyType> void print(Collection<AnyType> coll){
2   for(AnyType item : coll)
3       System.out.println(item);
4 }

3.3.2 Iterator接口

实现Iterable接口的集合必须提供一个iterator方法,该方法返回一个实现了Iterator接口的对象。该Iterator是在java.util包中定义的接口。

1 public interface Iterator<AnyType>
2 {
3     boolean hasNext( );
4     AnyType next( );
5     void remove( );
6 }

【xyl整理思路】

Collection接口扩展了Iterable接口,实现了Iterable接口的集合必须要提供一个iterator方法,这个方法返回一个实现了Iterator接口的对象。【从下面代码的角度更好理解这段话】

1 public static <AnyType> void print( Collection<AnyType> coll ) 
2 {
3     Iterator<AnyType> itr = coll.iterator( ); 
4     while( itr.hasNext( ) ) {
5         AnyType item = itr.next( ); 
6         System.out.println( item );
7     }     
8 }        

Iterator接口的remove方法:
可以删除由next最近返回的项(删除一次后,我们不能再调用remove,只有再对next调用一次后才可以remove)

Iteraror的remove方法和Collection的remove方法:
Iterator的remove方法的优点:
1、Collection的remove方法必须首先找出要被删除的项。
2、使用Iterator的一个基本法则:如果对正在被迭代的集合进行结构上的改变(即add、remove、clear方法),那么迭代器不再合法。Iterator的remove的方法除外。

 

3.3.3 List 接口、ArrayList 类和LinkedList 类

List 接口继承了 Collection 接口,它包含Collection接口的所有方法。下面解释了其中一些重要方法:

1 public interface List<AnyType> extends Collection<AnyType> {
2     AnyType get( int idx );
3     AnyType set( int idx, AnyType newVal ); 
4     void add( int idx, AnyType x ); 
5     void remove( int idx );
6 
7     ListIterator<AnyType> listIterator( int pos ); 
8 }

List 接口指定 listIterator 方法,它将产生比通常更复杂的迭代器,在 3.3.5 补充。

List ADT 有两种常见实现方式:1、ArrayList 类;2、LinkedList 类。

ArrayList 类

提供了 List ADT 的一种可增长数组的实现。

LinkedList 类

提供了 List ADT 的双链表实现。

本小节重点在于两者的区别:

ArrayList 类:查找快,增删慢;
LinkedList 类:增删快,查找慢。

 

3.3.4 例子:remove 方法对 LinkedList 类的使用

Iterator 接口的remove 方法,只花费线性时间。

public static void removeEvensVer3( List<Integer> lst ) {
    Iterator<Integer> itr = lst.iterator( ); 

    while( itr.hasNext( ) )
    if( itr.next( ) % 2 == 0 ) 
        itr.remove( );
}    

 

3.3.5 关于 ListIterator 接口

下面代码展示了 ListIterator 继承了  List 的 Iterator 的功能。方法 previous 和 hasPrevious 可以实现表从后向前的遍历。add 方法将一个新的项以当前位置放入表中。

public interface ListIterator<AnyType> extends Iterator<AnyType> {
  boolean hasPrevious( ); 
  AnyType previous( );   
  void add( AnyType x );
  void set( AnyType newVal );
}

 

3.4 ArrayList 类的实现

3.4.1 基本类

 1 public class MyArrayList<AnyType> implements Iterable<AnyType> {
 2         private static final int DEFAULT_CAPACITY = 10;
 3         private int theSize;
 4         private AnyType[] theItems;
 5 
 6         public MyArrayList() {
 7             doClear();
 8         }
 9 
10         public void clear() {
11             doClear();
12         }
13 
14         private void doClear() {
15             theSize = 0;
16             ensureCapacity(DEFAULT_CAPACITY);
17         }
18 
19         public int size() {
20             return theSize;
21         }
22 
23         public boolean isEmpty() {
24             return size() == 0;
25         }
26 
27         public void trimToSize() {
28             ensureCapacity(size());
29         }
30 
31         public AnyType get(int idx) {
32             if (idx < 0 || idx >= size()) throw new ArrayIndexOutOfBoundsException();
33             return theItems[idx];
34         }
35 
36         public AnyType set(int idx, AnyType newVal) {
37             if (idx < 0 || idx >= size())
38                 throw new ArrayIndexOutOfBoundsException();
39             AnyType old = theItems[idx];
40             theItems[idx] = newVal;
41             return old;
42         }
43 
44         public void ensureCapacity(int newCapacity) {
45             if (newCapacity < theSize) return;
46             AnyType[] old = theItems;
47             theItems = (AnyType[]) new Object[newCapacity];
48             for (int i = 0; i < size(); i++) theItems[i] = old[i];
49         }
50 
51         public boolean add(AnyType x) {
52             add(size(), x);
53             return true;
54         }
55 
56         public void add(int idx, AnyType x) {
57             if (theItems.length == size())
58                 ensureCapacity(size() * 2 + 1);
59             for (int i = theSize; i > idx; i--) theItems[i] = theItems[i - 1];
60             theItems[idx] = x;
61             theSize++;
62         }
63 
64         public AnyType remove(int idx) {
65             AnyType removedItem = theItems[idx];
66             for (int i = idx; i < size() - 1; i++) theItems[i] = theItems[i + 1];
67             theSize--;
68             return removedItem;
69         }
70 
71         public java.util.Iterator<AnyType> iterator() {
72             return new ArrayListIterator();
73         }
74 
75         private class ArrayListIterator implements java.util.Iterator<AnyType> {
76             private int current = 0;
77 
78             public boolean hasNext() {
79                 return current < size();
80             }
81 
82             public AnyType next() {
83                 if (!hasNext())
84                     throw new java.util.NoSuchElementException();
85                 return theItems[current++];
86             }
87 
88             public void remove() {
89                 MyArrayList.this.remove(--current);
90             }
91         }
92     }

 

ArrayListIterator 这里有一个 Java 结构,它是 MyArrayList 的内部类。

 

下面则是 嵌套类

 1 public class MyArrayList<AnyType> implements Iterable<AnyType> {
 2         private int theSize;
 3         private AnyType[] theItems; ...
 4 
 5         public java.util.Iterator<AnyType> iterator() {
 6             return new ArrayListIterator<AnyType>(this);
 7         }
 8 
 9         private static class ArrayListIterator<AnyType> implements java.util.Iterator<AnyType> {
10             private int current = 0;
11             private MyArrayList<AnyType> theList; ...
12 
13             public ArrayListIterator(MyArrayList<AnyType> list) {
14                 theList = list;
15             }
16 
17             public boolean hasNext() {
18                 return current < theList.size();
19             }
20 
21             public AnyType next() {
22                 return theList.theItems[current++];
23             }
24         }
25     }

 

嵌套类和内部类的区别是,必须使用 static 来表示是嵌套的;没有 static 则是内部类。

嵌套类可以被设计成 private

 

补充知识:内部类、外部类

内部类:类的第五个成员
1.定义:Java中允许将一个类A声明在另一个类B中,则类A就是内部类,类B称为外部类.
2.内部类的分类:
成员内部类(静态、非静态 ) vs 局部内部类(方法内、代码块内、构造器内)
3.成员内部类的理解:
一方面,作为外部类的成员:
调用外部类的结构
可以被static修饰(嵌套类)
可以被4种不同的权限修饰

另一方面,作为一个类:
类内可以定义属性、方法、构造器等
可以被final修饰,表示此类不能被继承。言外之意,不使用final,就可以被继承
可以被abstract修饰
4.成员内部类:
4.1如何创建成员内部类的对象?(静态的,非静态的)

1 //创建静态的Dog内部类的实例(静态的成员内部类):
2 Person.Dog dog = new Person.Dog();
3 
4 //创建非静态的Bird内部类的实例(非静态的成员内部类):
5 //Person.Bird bird = new Person.Bird();//错误的
6 Person p = new Person();
7 Person.Bird bird = p.new Bird();


4.2如何在成员内部类中调用外部类的结构?⭐

 1 public class Person {
 2     String name = "小明";
 3     public void eat(){
 4     }
 5     //非静态成员内部类
 6     class Bird{
 7         String name = "杜鹃";
 8         public void display(String name){
 9             System.out.println(name);//方法的形参
10             System.out.println(this.name);//内部类的属性
11             System.out.println(Person.this.name);//外部类的属性
12             //Person.this.eat();
13         }
14     }  
15 }


5.局部内部类的使用:

//返回一个实现了Comparable接口的类的对象
    public Comparable getComparable(){

        //创建一个实现了Comparable接口的类:局部内部类
        //方式一:
//        class MyComparable implements Comparable{
//
//            @Override
//            public int compareTo(Object o) {
//                return 0;
//            }           
//        }       
//        return new MyComparable();

        //方式二:
        return new Comparable(){

            @Override
            public int compareTo(Object o) {
                return 0;
            }
        };
    }

 

注意点:
在局部内部类的方法中(比如:show如果调用局部内部类所声明的方法(比如:method)中的局部变量(比如:num)的话,要求此局部变量声明为final的。

jdk 7及之前版本:要求此局部变量显式的声明为final的
jdk 8及之后的版本:可以省略final的声明
总结:
成员内部类和局部内部类,在编译以后,都会生成字节码文件。
格式:成员内部类:外部类$内部类名.class
局部内部类:外部类$数字 内部类名.class

3.5 LinkedList 类的实现

 1 public class MyLinkedList<AnyType> implements Iterable<AnyType> {
 2     private static class Node<AnyType> {/* Figure 3.25 */
 3     }
 4 
 5     public MyLinkedList() {
 6         doClear();
 7     }
 8 
 9     public void clear() {/* Figure 3.26 */}
10 
11     public int size() {
12         return theSize;
13     }
14 
15     public boolean isEmpty() {
16         return size() == 0;
17     }
18 
19     public boolean add(AnyType x) {
20         add(size(), x);
21         return true;
22     }
23 
24     public void add(int idx, AnyType x) {
25         addBefore(getNode(idx, 0, size()), x);
26     }
27 
28     public AnyType get(int idx) {
29         return getNode(idx).data;
30     }
31 
32     public AnyType set(int idx, AnyType newVal) {
33         Node<AnyType> p = getNode(idx);
34         AnyType oldVal = p.data;
35         p.data = newVal;
36         return oldVal;
37     }
38 
39     public AnyType remove(int idx) {
40         return remove(getNode(idx));
41     }
42 
43     private void addBefore(Node<AnyType> p, AnyType x) {/* Figure 3.28 */}
44 
45     private AnyType remove(Node<AnyType> p) {/* Figure 3.30 */}
46 
47     private Node<AnyType> getNode(int idx) {/* Figure 3.31 */}
48 
49     private Node<AnyType> getNode(int idx, int lower, int upper) {/* Figure 3.31 */}
50 
51     public java.util.Iterator<AnyType> iterator() {
52         return new LinkedListIterator();
53     }
54 
55     private class LinkedListIterator implements java.util.Iterator<AnyType> {/* Figure 3.32 */
56     }
57 
58     private int theSize;
59     private int modCount = 0;
60     private Node<AnyType> beginMarker;
61     private Node<AnyType> endMarker;
62 }

 

MyLinkedList 类的嵌套 Node 类

 1 private static class Node<AnyType> {
 2     public Node(AnyType d, Node<AnyType> p, Node<AnyType> n) {
 3         data = d;
 4         prev = p;
 5         next = n;
 6     }
 7 
 8     public AnyType data;
 9     public Node<AnyType> prev;
10     public Node<AnyType> next;
11 }

 

MyLinkedList 类的 clear 例程

 1 public void clear(){
 2     doClear();
 3 }
 4 private void doClear(){
 5     beginMarker = new Node<AnyType>(null,null,null);
 6     endMarker = new Node<AnyType>(null,beginMarker,null);
 7     beginMarker.next = endMarker;
 8     
 9     theSize=0;
10     modCount++;
11 }

 

MyLinkedList 类的 add 例程

 1 /**
 2  * Adds an item to this collection, at specified position p. 
 3  * Items at or after that position are slid one position higher.
 4  * @param p Node to add before. 
 5  * @param x any object.
 6  * @throws IndexOutOfBoundsException if idx is not between 0 and size(),.
 7  */
 8 private void addBefore(Node<AnyType> p, AnyType x) {
 9     Node<AnyType> newNode = new Node<>(x, p.prev, p);
10     newNode.prev.next = newNode;
11     p.prev = newNode;
12     theSize++;
13     modCount++;
14 }

 

MyLinkedList 类的 remove 例程

MyLinkedList 类的 getNode 例程

MyLinkedList 类的的内部 Iterator 类

3.6 栈 ADT

 

posted @ 2021-05-02 10:34  就叫小月亮  阅读(122)  评论(0)    收藏  举报