Erlo

第24章 实现线性表,栈,队列和优先队列

2019-04-18 18:01:42 发布   122 浏览  
页面报错/反馈
收藏 点赞

线性表的通用特性

1.实现线性表的方式:

   1)数组(arrray):数组大小是固定的。如果元数个数超过了数组的容量,就创建一个更大的数组,并将当前数组的元素复制到新数组中。

   2)链式结构(linked structure):链式结构是由节点组成,每个节点都是动态创建的。用来储存一个元素。所有的节点链接成一个线性表。

{*}设计指南:通用的操作可以归纳为一个接口或一个抽象类。一个好的策略就是在设计中提供接口和便利抽象类,以整合抽象类和接口的优点。抽象类提供了接口的骨架实现,可以更有效的实现接口。

 

我们把这样的接口命名为MyList,把便利类命名为MyAbtractList.

 

下面是MyList的源代码

 1 package List_24;
 2 
 3 import java.util.Collection;
 4 
 5 public interface $24_01MyList<E> extends Collection<E> {
 6     /** Add a new element at the specified index in this list */
 7     public void add(int index, E e);
 8 
 9     /** Return the element from this list at the specified index */
10     public E get(int index);
11 
12     /**
13      * Return the index of the first matching element in this list. Return -1 if no
14      * match.
15      */
16     public int indexOf(Object e);
17 
18     /**
19      * Return the index of the last matching element in this list Return -1 if no
20      * match.
21      */
22     public int lastIndexOf(E e);
23 
24     /**
25      * Remove the element at the specified position in this list Shift any
26      * subsequent elements to the left. Return the element that was removed from the
27      * list.
28      */
29     public E remove(int index);
30 
31     /**
32      * Replace the element at the specified position in this list with the specified
33      * element and returns the new set.
34      */
35     public E set(int index, E e);
36 
37     @Override /** Add a new element at the end of this list */
38     public default boolean add(E e) {
39         add(size(), e);
40         return true;
41     }
42 
43     @Override /** Return true if this list contains no elements */
44     public default boolean isEmpty() {
45         return size() == 0;
46     }
47 
48     @Override /**
49                  * Remove the first occurrence of the element e from this list. Shift any
50                  * subsequent elements to the left. Return true if the element is removed.
51                  */
52     public default boolean remove(Object e) {
53         if (indexOf(e) >= 0) {
54             remove(indexOf(e));
55             return true;
56         } else
57             return false;
58     }
59 
60     @Override
61     public default boolean containsAll(Collection<?> c) {
62         // Left as an exercise
63         return true;
64     }
65 
66     @Override
67     public default boolean addAll(Collection<? extends E> c) {
68         // Left as an exercise
69         return true;
70     }
71 
72     @Override
73     public default boolean removeAll(Collection<?> c) {
74         // Left as an exercise
75         return true;
76     }
77 
78     @Override
79     public default boolean retainAll(Collection<?> c) {
80         // Left as an exercise
81         return true;
82     }
83 
84     @Override
85     public default Object[] toArray() {
86         // Left as an exercise
87         return null;
88     }
89 
90     @Override
91     public default <T> T[] toArray(T[] array) {
92         // Left as an exercise
93         return null;
94     }
95 }

下面是MyAstractList的源代码

 1 package List_24;
 2 
 3 public abstract class $24_02MyAbstractList<E> implements $24_01MyList<E> {
 4     protected int size = 0; // The size of the list
 5 
 6 /** Create a default list */
 7 protected $24_02MyAbstractList() {
 8 }
 9 
10 /** Create a list from an array of objects */
11 protected $24_02MyAbstractList(E[] objects) {
12   for (int i = 0; i < objects.length; i++)
13     add(objects[i]);
14 }
15 
16     @Override /** Add a new element at the end of this list */
17     public void add(E e) {
18         add(size, e);
19     }
20 
21     @Override /** Return true if this list contains no elements */
22     public boolean isEmpty() {
23         return size == 0;
24     }
25 
26     @Override /** Return the number of elements in this list */
27     public int size() {
28         return size;
29     }
30 
31     @Override /**
32                  * Remove the first occurrence of the element e from this list. Shift any
33                  * subsequent elements to the left. Return true if the element is removed.
34                  */
35     public boolean remove(E e) {
36         if (indexOf(e) >= 0) {
37             remove(indexOf(e));
38             return true;
39         } else
40             return false;
41     }
42 }

24.3数组线性表

{*}数组线性表采用数组来实现

{*}该数据数组的类型是E[]类型,所以数组中每个元素实际储存的时对象的引用

 

下面是TestArrayList的源代码

 1 package List_24;
 2 
 3 public class $24_04TestArrayList {
 4     public static void main(String[] args) {
 5         // Create a list
 6         $24_03MyArrayList<String> list = new $24_03MyArrayList<>();
 7 
 8         // Add elements to the list
 9         list.add("America"); // Add it to the list
10         System.out.println("(1) " + list);
11 
12         list.add(0, "Canada"); // Add it to the beginning of the list
13         System.out.println("(2) " + list);
14 
15         // Add elements to the list
16         list.add("Russia"); // Add it to the end of the list
17         System.out.println("(3) " + list);
18         
19         // Add elements to the list
20         list.add("France"); // Add it to the end of the list
21         System.out.println("(4) " + list);
22 
23         list.add(2, "Germany"); // Add it to the list at index 2
24         System.out.println("(5) " + list);
25 
26         list.add(5, "Germany"); // Add it to the list at index 5
27         System.out.println("(6) " + list);
28         
29         //Remove elements from the list
30         list.remove("Canada");//Same sa list.remove(0) in this case
31         System.out.println("(7) " + list);
32         
33         list.remove(2);//Remove the element at index 2
34         System.out.println("(8) " + list);
35         
36         list.remove(list.size()-1);//Remove the last element
37         System.out.print("(9) "+list+"n(10) ");
38         
39         for(String s:list) {
40             System.out.print(s.toUpperCase()+" ");
41         }
42     }
43 }

24.4链表

{*}链表采用链接结构实现

当需要移动大量元素时数组实现的线性表效率很低,这种情况下采用链式结构来实现线性表。

 24.4.1节点

链表中的每个元素都包含一个成为节点的结构。当向链表中加入一个新的元素时,就会产生一个包含它的节点。每个节点都和它的相邻节点相链接。

节点可以按如下定义为一个类:

1 class Node<E> {
2     E element;
3     Node<E> next;
4 
5     public Node(E e) {
6         element = e;
7     }
8 }

在这里,变量head指向线性表的第一个节点,而变量tail指向最后一个节点。如果线性表为空,这两个线性表均为null。

 

例子:创建一个储存三个结点的链表,每个节点储存一个字符串元素。

  步骤一:声明head和tail

  Node<String> head=null;

  Node<String> tail=null;

  步骤二:

  创建第一个节点并将它追加到线性表中

  head=new Node<>("Chicago");

  tail=head;

  步骤三:

  创建第二个节点并将它追加到线性表中

  tail.next=new Node<>("Denver");

  tail=tail.next;

  步骤四:

  创建第三个节点并将它追加到线性表中

  tail.next=new Node<>("Dallas");

  tail=tail.next;

 

每个节点都包含元素和一个名为next的数据域,next指向下一个元素。如果节点是线性表的最后一个,那么它的指针数据域next所包含的值是null.可以使用这个特性来检测某节点是否是最后节点。

例如:下面代码可用来遍历线性表的所有节点

Node current = head;
while(current != null){
    System.out.println(current.element);
    current = current.next();
}

24.4.2MyLinkList类

MyLinkList类使用链式结构实现动态线性表,它继承自MyAbstractList类。

 

假设已经实现了这个类,下面给出该类的测试程序。

 1 package List_24;
 2 
 3 public class $24_05TestMyLinkedList {
 4     /** Main method */
 5     public static void main(String[] args) {
 6         // Create a list for strings
 7         $24_06MyLinkedList<String> list = new $24_06MyLinkedList<>();
 8 
 9         // Add elements to the list
10         list.add("America"); // Add it to the list
11         System.out.println("(1) " + list);
12 
13         list.add(0, "Canada"); // Add it to the beginning of the list
14         System.out.println("(2) " + list);
15 
16         list.add("Russia"); // Add it to the end of the list
17         System.out.println("(3) " + list);
18 
19         list.addLast("France"); // Add it to the end of the list
20         System.out.println("(4) " + list);
21 
22         list.add(2, "Germany"); // Add it to the list at index 2
23         System.out.println("(5) " + list);
24 
25         list.add(5, "Norway"); // Add it to the list at index 5
26         System.out.println("(6) " + list);
27 
28         list.add(0, "Poland"); // Same as list.addFirst("Poland")
29         System.out.println("(7) " + list);
30 
31         // Remove elements from the list
32         list.remove(0); // Same as list.remove("Australia") in this case
33         System.out.println("(8) " + list);
34 
35         list.remove(2); // Remove the element at index 2
36         System.out.println("(9) " + list);
37 
38         list.remove(list.size() - 1); // Remove the last element
39         System.out.print("(10) " + list + "n(11) ");
40 
41         for (String s : list)
42             System.out.print(s.toUpperCase() + " ");
43 
44         list.clear();
45         System.out.println("nAfter clearing the list, the list size is " + list.size());
46     }
47 }

24.4.3实现MyLinkedList

下面提供该类的具体实现。

  1 package List_24;
  2 
  3 public class $24_06MyLinkedList<E> extends $24_02MyAbstractList<E> {
  4     private Node<E> head, tail;
  5     private int size = 0; // Number of elements in the list
  6 
  7     /** Create an empty list */
  8     public $24_06MyLinkedList() {
  9     }
 10 
 11     /** Create a list from an array of objects */
 12     public $24_06MyLinkedList(E[] objects) {
 13         for (int i = 0; i < objects.length; i++)
 14             add(objects[i]);
 15     }
 16 
 17     /** Return the head element in the list */
 18     public E getFirst() {
 19         if (size == 0) {
 20             return null;
 21         } else {
 22             return head.element;
 23         }
 24     }
 25 
 26     /** Return the last element in the list */
 27     public E getLast() {
 28         if (size == 0) {
 29             return null;
 30         } else {
 31             return tail.element;
 32         }
 33     }
 34 
 35     /** Add an element to the beginning of the list */
 36     public void addFirst(E e) {
 37         Node<E> newNode = new Node<>(e); // Create a new node
 38         newNode.next = head; // link the new node with the head
 39         head = newNode; // head points to the new node
 40         size++; // Increase list size
 41 
 42         if (tail == null) // the new node is the only node in list
 43             tail = head;
 44     }
 45 
 46     /** Add an element to the end of the list */
 47     public void addLast(E e) {
 48         Node<E> newNode = new Node<>(e); // Create a new for element e
 49 
 50         if (tail == null) {
 51             head = tail = newNode; // The new node is the only node in list
 52         } else {
 53             tail.next = newNode; // Link the new with the last node
 54             tail = newNode; // tail now points to the last node
 55         }
 56 
 57         size++; // Increase size
 58     }
 59 
 60     @Override /**
 61                  * Add a new element at the specified index in this list. The index of the head
 62                  * element is 0
 63                  */
 64     public void add(int index, E e) {
 65         if (index == 0) {
 66             addFirst(e);
 67         } else if (index >= size) {
 68             addLast(e);
 69         } else {
 70             Node<E> current = head;
 71             for (int i = 1; i < index; i++) {
 72                 current = current.next;
 73             }
 74             Node<E> temp = current.next;
 75             current.next = new Node<>(e);
 76             (current.next).next = temp;
 77             size++;
 78         }
 79     }
 80 
 81     /**
 82      * Remove the head node and return the object that is contained in the removed
 83      * node.
 84      */
 85     public E removeFirst() {
 86         if (size == 0) {
 87             return null;
 88         } else {
 89             E temp = head.element;
 90             head = head.next;
 91             size--;
 92             if (head == null) {
 93                 tail = null;
 94             }
 95&
登录查看全部

参与评论

评论留言

还没有评论留言,赶紧来抢楼吧~~

手机查看

返回顶部

给这篇文章打个标签吧~

棒极了 糟糕透顶 好文章 PHP JAVA JS 小程序 Python SEO MySql 确认