鏈表,隊列,堆棧

一. 鏈表

1.定義
        鏈表(Linked list)是一種常見的基礎數據結構,是一種線性表,但是並不會按線性的順序存儲數據,而是在由一個個節點組成,每個節點(node)中儲存着數據變量(data)和指針變量(node next),又有一個頭節點(head)連接下面的節點,而最後一個節點指向空(null)。可以在鏈表類中定義增加,刪除,插入,遍歷,修改等方法,故常用來儲存數據。  
2. 優點
      (1).使用鏈表結構可以克服數組鏈表需要預先知道數據大小的缺點,鏈表結構可以充分利用計算機內存空間,實現靈活的內存動態管理。       (2).數據的存取往往要在不同的排列順序中轉換,而鏈表是一種自我指示數據類型,因爲它包含指向另一個相同類型的數據的指針(鏈接)。鏈表允許插入和移除表上任意位置上的節點,但是不允許隨機存取。  
3. 缺點
        鏈表失去了數組隨機讀取的優點,同時鏈表由於增加了結點的指針域,空間開銷比較大。  
4. 類型
        主要有單向鏈表,雙向鏈表以及循環鏈表。

5. 與數組(Array)的對比
        鏈表的使用不需要知道數據的大小,而數組在創建時必須指明數組的大小。         鏈表沒有對應的下標,只有指向下一個數據的指針,而數組中每一個都有一個相對應的下標。
        鏈表在內存中儲存的數據可以是不連續的,而數組儲存的數據佔內存中連續的一段,用標識符標識。

二. 隊列 1. 定義
        隊列是一種特殊的線性表,它只允許在表的前端(front)進行刪除操作,而在表的後端(rear)進行插入操作。進行插入操作的端稱爲隊尾,進行刪除操作的端稱爲隊頭。隊列中沒有元素時,稱爲空隊列。         在隊列這種數據結構中,最先插入的元素將是最先被刪除的元素;反之最後插入的元素將最後被刪除的元素,因此隊列又稱爲“先進先出”(FIFO—first in first out)的線性表。  
2. 隊列的方法
add(E e)     將指定的元素插入此隊列(如果立即可行且不會違反容量限制),在成功時返
回 true,如果當前沒有可用的空間,則拋出 IllegalStateException。返回boolean。
element()    獲取不移除此隊列的頭,如果此隊列爲空,則拋出NoSuchElementException,
返回泛型E。
offer(E e)    將指定的元素插入此隊列(如果立即可行且不會違反容量限制),當使用有容
量限制的隊列時,此方法通常要優於 add(E),後者可能無法插入元素,而只是拋出一個異常。返回boolean。
peek()       獲取不移除此隊列的頭,如果此隊列爲空,則返回 null。返回泛型E。 poll()        獲取並移除此隊列的頭,如果此隊列爲空,則返回 null。返回泛型E。 remove()     獲取並移除此隊列的頭。返回泛型E。  
3. 隊列的使用和假溢出
        隊列可以用數組Q[1„m]來存儲,數組的上界是m,最大容量是m。在隊列的運算中需設兩個指針:隊頭指針(head),指向實際隊頭元素的前一個位置;隊尾指針(tail),指向實際隊尾元素所在的位置,隊列中擁有的元素個數爲:N=tail-head。一般情況下,兩個指針的初值設爲0,這時隊列爲空,沒有元素。
       若數組定義Q[1„10],head=2,tail=8。如果要讓排頭的元素出隊,則需將頭指針加1。即head=head+1這時頭指針向上移動一個位置,指向Q(3),表示Q(3)已出隊。如果想讓一個新元素入隊,則需尾指針向上移動一個位置。即tail=tail+1這時Q(9)入隊。當隊尾已經處理在最上面時,即tail=10,如果還要執行入隊操作,則要發生"上溢",但實際上隊列中還有三個空位置,所以這種溢出稱爲"假溢出"。

4. 循環隊列的概念
        爲充分利用向量空間,克服"假溢出"現象的方法是:將向量空間想象爲一個首尾相接的圓環,並稱這種向量爲循環向量。存儲在其中的隊列稱爲循環隊列(Circular Queue)。         循環隊列的入隊算法:        (1). tail=tail+1;
    (2). 若tail=m+1,則tail=1;
       (3). 若head=tail尾指針與頭指針重合了,判斷空或滿;        (4). 否則,Q[tail]=X,結束(X爲新入出元素)。         循環隊列的出隊算法:
       (1). 若head=tail尾指針與頭指針重合了,判斷空或滿;         (2). 若不重合head=head+1;        (3). 若head=m+1,則head=1;        (4). 移除Q[head],結束。
        循環隊列中,由於入隊時尾指針向前追趕頭指針;出隊時頭指針向前追趕尾指針,造成隊空和隊滿時頭尾指針均相等。因此,無法通過條件front==rear來判別隊列是"空"還是"滿"。 
        解決這個問題的方法至少有兩種:    ① 另設一布爾變量以區別隊列的空和滿;
   ② 另一種方式就是數據結構常用的: 隊滿時:(tail+1)%n=head,n爲隊列長度(所用數組大小),由於tail,head均爲所用空間的指針,循環只是邏輯上的循環,所以需要求餘運算。如圖情況,隊已滿,但是tail+1=5+1=6,n=6,求餘6%6=0=head。 
   
 
 5. 阻塞隊列(BlockingQueue)的概念       
三. 棧      1. 定義
        棧(Stack),是硬件。主要作用表現爲一種數據結構,是隻能在某一端插入和刪除的特殊線性表。它按照後進先出的原則存儲數據,先進入的數據被壓入棧底,最後的數據在棧頂,需要讀數據的時候從棧頂開始彈出數據(最後一個數據被第一個讀出來)。

      棧是允許在同一端進行插入和刪除操作的特殊線性表。允許進行插入和刪除操作的一端稱爲棧頂(top),另一端爲棧底(bottom);棧底固定,而棧頂浮動;棧中元素個數爲零時稱爲空棧。插入一般稱爲進棧(PUSH),刪除則稱爲退棧(POP)。 棧也稱爲先進後出表。  
2. 棧的方法
empty()  測試堆棧是否爲空。返回boolean。
peek()     查看堆棧頂部的對象,但不從堆棧中移除它。返回泛型E。
pop()        移除堆棧頂部的對象,並作爲此函數的值返回該對象。返回泛型E。 push(E item)   把項壓入堆棧頂部。返回泛型E。
search(Object o)   返回對象在堆棧中的位置,以 1 爲基數。返回int。  
 
3. 棧的實現
        1、進棧(PUSH)算法  
  ①若TOP≥n時,則給出溢出信息,作出錯處理(進棧前首先檢查棧是否          已滿,滿則溢出;不滿則作②);
  ②置TOP=TOP+1(棧指針加1,指向進棧地址);   ③S(TOP)=X,結束(X爲新進棧的元素);  
  2、退棧(POP)算法
  ①若TOP≤0,則給出下溢信息,作出錯處理(退棧前先檢查是否已爲空棧,            空則下溢;不空則作②);   ②X=S(TOP),(退棧後的元素賦給X):
③TOP=TOP-1,結束(棧指針減1,指向棧頂)。

鏈表,隊列,堆棧的區別:

1、棧是個有底的口袋,像襪子。
隊列是沒底的口袋,像通心粉。
所以:棧的特點是先進後出,隊列的特點是先進先出。
2、主要區別是適用的地方不一樣,  
  鏈表實際上可以認爲是一種數據的物理組織形式,是用指針或對象的引用組織起的一種數據的存儲方式.  
  隊列和堆棧是一個更高層次的概念,其底層可以是用鏈表也可以是用數組來實現.  
  隊列和堆棧的主要區別是進出的順序不一樣,  
  隊列是先進先出,堆棧是後進先出.  
3、cooled(經典中--經過非典中)   說的很詳細了,我補充一下  
  隊列和堆棧是一種特殊的數據組織形式。  
  可以把他們看成是一系列的集合。  
  隊列可以看成是有2個口的集合一個口叫隊頭一個叫隊尾,只能在對頭進行刪除操作,在隊尾做插入。根據這樣的操作。隊列特點是先進先出  
  堆棧可以看成是有1個口的集合,這個口叫棧頂。插入和刪除操作只能在棧頂操作。根據這樣的操作。堆棧的特點是是後進先出.  

  鏈表是一種存儲方式,它可以在非連續的內存空間裏面存儲一個集合的元素。和它對應的是數組,數組要在連續的空間裏存儲集合的元素


總的來說: 

三者都是邏輯結構,各有特性。線性表是一個含有n個元素的有序序列,形成線性結構。這種結構只有一個“第一個元素”和一個“最後一個元素”,除“第一個元素”之外每個元素都有一個前驅,除“最後一個元素”之外每個元素都有一個後繼。對線性表附加存取限制可以得到棧和隊列。棧只允許在棧頂進行存取,有“後進先出”的特性。隊列只允許在隊尾存,在隊首取,有先進先出的特性。三種結構有不同的應用。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章