1. 程式人生 > >《資料結構與演算法分析java語言描述》知識點總結(3-4章)

《資料結構與演算法分析java語言描述》知識點總結(3-4章)

3. 表、棧、佇列

3.1 抽象資料型別(ADT)

  • 表的一些簡單操作可以通過使用陣列來完成,如果發生對錶的一些插入和刪除操作,特別是對錶的前端進行,那麼陣列就不是一種很好的選擇了,就需要使用連結串列了。連結串列的查詢效率低不如陣列,但是其插入和刪除方便。

3.2 Java CollectionsAPI中的表

Java.util包中Collection介面的子集有:size()、isEmpty()、clear()、contains()、add()、remove()、iterator()。

3.2.1 Iterator 介面

  • Iterator介面集合必提供一個稱為iterator()的方法,該方法返回一個叫做Iterator型別的物件。其包含的方法有hasNext()、next()、remove();hasNext用來告訴是否存在下一項。

3.2.2 List介面,ArrayList類和LinkedList類

  • List(有序,可重複)介面繼承了Collection介面的所有方法,外加其他的一些方法。如:get(int idx)、set(int idx,AnyType newVd)、add(int idx,AnyType x),remove(int idx),listIterator(int pos).

ArrayList、LinkedList、vector區別:

ArrayList:底層資料結構是陣列。特點:查詢快、增刪慢、執行緒不同步、效率高。

LinkedList:底層資料結構是連結串列。特點:查詢慢、增刪快、執行緒不同步、效率高。

vector:底層資料結構是陣列。特點:查詢快、增刪慢、執行緒同步、效率低,被ArrayList代替了。

LinkedList對get的呼叫效率不高,對remove呼叫同樣低效,為了提高效率用一個迭代器一步步遍歷該表。

public static void removeEventver3(List<Integer>lst)
{
  Iterator <Integer> itr=lst.iterator();
  while(itr.hasNext())
  if(itr.next()%2==0)
      itr.remove();
}
刪除表中的偶數,對ArrayList是二次的,但對LinkedList是線性的。

3.2.1 關於ListIterator 介面

ListIterator擴充套件了List的Iterator 功能,方法pervious,hasprevious使得對錶從後向前的遍歷得以完成,add方法將一個新的項以當前位置放入表中,還有一個set()方法

3.3ArrayList類的實現

內部方法包括:clear(),size(),isEmpty(),trimTosize(),get(int idx),set(int idx,AnyType newval),ensureCapacity(int newCapacity),add(AnyType x),add(int idx,AnyType x),remove(int idx),iterator()...

3.3LinkedList類的實現

連結串列的插入圖:
Node newNode=new Node(x,p.prev,p);//1,2步
p.prev.next=newNode;//3步
p.prev=newNode;//4步
第3步,和第4步合併後:
Node newNode=new Node(x,p.prev,p);//1,2
p.prev=p.prev.next=newNode;//3,4

LinkedList包括的方法有:clear(),size(),isEmpty(),add(AnyType x),add(int idx,AnyType x),get(int idx),set(int idx,Anytype newval),remove(int idx),addBefore(Node<Anytype>p,Anytype x),remove(Node<Anytype> p),getNode(int idx).

從雙鏈表刪除右P指定的節點: p.next.prev=p.prev; p.prev.next=p.next;

3.4 棧的ADT

棧:限制插入與刪除只能在一個位置的表,有時又叫LIFO(後進後出表),通過push向棧輸入,通過pop和top從棧中輸出。
  • 由於棧是一個表,因此如何實現表的方法都可以實現棧
棧的應用:平衡符號,字尾表示式,中綴到字尾的轉換,方法呼叫 計算字尾表示式花費的時間是:O(N)

3.4 佇列的ADT

像棧一樣,佇列(queue)也是表,使用佇列時,插入在一端刪除在另一端進行。 enqueue(入隊),在末端(堆尾(rear))插入一個元素 dequeue(出隊),在表頭(又叫隊頭(front))刪除 連結串列實現和陣列實現都給出了快速的o(1)執行時間。

4.  樹

  • 對於大量的輸入資料,連結串列的執行時間太慢,不宜使用。本章將討論一種簡單的資料結構,其大部分執行時間平均為o(log N)
  • 二叉查詢數是兩種庫集合TreeSet和TreeMap實現的基礎

4.1 具備知識

  • 樹(Tree)的一種自然方式是遞迴方式,一顆樹是一些節點的集合,如圖:
一棵樹是N個節點和N條邊的集合
  • 樹的遍歷分為:前序遍歷,後序遍歷,中序遍歷,層次遍歷

4.2 二叉樹

二叉樹其深度平均值為:o(logN).

4.2 表示式樹

4.3 查詢樹ADT---二叉查詢樹

性質:對於樹中的每個節點X,它的左子樹所有項小於X中項,而它的右子樹所有的項大於X中的項。 二叉查詢樹的一些方法:contains()、findMin()、findMax() 採用遞迴方式: private BinaryNode<AnyType> findMin(BinaryNode<Anytype> t)
{
    if(t==null)
        return null;
    else if(t.left==null)
        return t;
    return fi
ndMin(t.left);
}
//採用非遞迴方式:
private BinaryNode<AnyType> findMax(BinaryNode<Anytype> t)
{
    if(t!=null)
        return null;
    while(t.right!=null)
        t=t.right;
    return t;
}
//insert方法:
private BinaryNode<AnyType> insert(Anytype x,BinaryNode<Anytype>  t)
{
    if(t!=null)
        return new BinaryNode<AnyType>(x,null,null);
int compareResult=x.compareTo(t.element);
if(compareResult<0)
       t.left=insert(x,t.left);
else if(compareResult>0)
       t.right=iinsert(x,t.right);
else
       ;
    return t;
}

4.4 AVL樹

Avl樹是帶有平衡條件的二叉查詢樹,它保證了樹的深度是o(logn),要求左右子樹具有相同的高度。
  • 插入操作隱含困難在於,插入一個節點可能破壞AVL樹的特性,我們通過旋轉來對它進行修正。
分以下兩種情況: 1. 第一種情況在”外邊”的情況: 左---左或者右---右                      單旋轉 2. 第二種情況在“內部”情況: 左---右或者右---左                      雙旋轉