數據結構包括邏輯結構和存儲結構。
邏輯結構包括集合、線性結構、樹形結構、圖形結構。
存儲結構包括順序存儲結構、鏈式存儲結構、索引存儲結構、哈希存儲結構。
“線性表”中的“線性”是邏輯結構的概念,是指
(1)開始結點和終端結點都是唯一的;
(2)除了開始結點和終端結點,其余結點都有且僅有一個直接前驅,有且僅有一個直接后繼。
“循環鏈表”中的“鏈表”是存儲結構的概念,是指
不要求邏輯上相鄰的結點在物理上也相鄰,結點間的邏輯關系是由附加的指針字段表示的。
綜上 ,循環鏈表也是鏈表的一種,鏈表滿足線性表的條件,所以循環鏈表自然也屬於線性表。
棧,它是一種運算受限的線性表。其限制是僅允許在表的一端進行插入和刪除運算。這一端被稱為棧頂,相對地,把另一端稱為棧底。
隊列,是一種特殊的 線性表 ,特殊之處在於它只允許在表的前端( front )進行刪除操作,而在表的后端( rear )進行插入操作,和棧一樣,隊列是一種操作受限制的線性表。進行插入操作的端稱為隊尾,進行刪除操作的端稱為隊頭
遞歸是棧實現的。棧是先進后出,也就是上次遞歸調用的時候,保存在棧頂, 在返回的時候出棧,所以是遞歸是依靠棧實現的.
PS: 非遞歸形式的深度優先搜索要用棧,而廣度優先使用了隊列。
某帶鏈的隊列初始狀態為 front=rear=NULL 。經過一系列正常的入隊與退隊操作后, front=rear=10 。該隊列中的元素個數為( )
往隊列的隊尾插入一個元素為入隊,從隊列的排頭刪除一個元素稱為退隊。初始時 front=rear=0 , front 總是指向隊頭元素的前一位置,入隊一次 rear+1 ,退隊一次 front+1 。隊列隊頭隊尾指針相同時隊列為空。而帶鏈的隊列,由於每個元素都包含一個指針域指向下一個元素,當帶鏈隊列為空時 front=rear=Null ,插入第 1 個元素時, rear+1 指向該元素, front+1 也指向該元素,插入第 2 個元素時 rear+1 , front 不變,刪除 1 個元素時 front+1 。即 front=rear 不為空時帶鏈的隊列中只有一個元素。
當隊列中只有一個元素時,出隊后需要清空對頭和隊尾指針。
線性結構與非線性結構,主要看元素之間的關系,如果是一對一的關系則是線性表,如果不是一對一的關系則是非線性表。
循環隊列中,由於入隊時尾指針向前追趕頭指針;出隊時頭指針向前追趕尾指針,造成隊空和隊滿時頭尾指針均相等。因此,無法通過條件front==rear來判別隊列是"空"還是"滿"。
解決這個問題的方法至少有兩種:
① 另設一布爾變量以區別隊列的空和滿;
②另一種方式就是數據結構常用的: 隊滿時:(rear+1)%n==front,n為隊列長度(所用數組大小),由於rear,front均為所用空間的指針,循環只是邏輯上的循環,所以需要求余運算.
隊列元素=(尾指針-頭指針+隊列容量)%隊列容量。循環隊列中的元素個數隨隊頭指針與隊尾指針的變化而動態變化
雙端隊列是一種同時具有隊列和棧的性質的一種數據結構,在隊列的兩頭都可以進行插入和刪除的操作;輸入受限的雙端隊列是指只能從隊列一端輸入,可以從兩端輸出的雙端隊列;同理,輸出受限的雙端隊列是指只能從隊列一端輸出,可以從兩端輸入的雙端隊列;如果雙端隊列允許從一端輸入,從一端輸出,則是普通的隊列,如果雙端隊列只允許從一端輸入和輸出則是棧。因此說雙端隊列同時具有隊列和棧兩種數據結構的性質。
Redis和kafka都是常見的開源隊列。
隊列是一種操作受限 的結構,即只能在隊首刪除和隊尾插入
棧是解決封閉對應問題的有效方法。
比如在解析XML中,遇到一個<demo>標簽(左標簽)就入棧,遇到其子標簽的左標簽(如<subdemo>)同樣入棧。遇到右標簽(如</subdemo>或</demo>)就校驗棧頂標簽是否與該右標簽對應,能對應就出棧,不能對應則說明標簽不對稱,是無效的XML文件
存儲結構是數據的邏輯結構用計算機語言的實現,常見的存儲結構有: 順序存儲 , 鏈式存儲 , 索引存儲 ,以及 散列存儲 。其中散列所形成的存儲結構叫 散列表(又叫哈希表) ,因此哈希表也是一種存儲結構。棧只是一種抽象數據類型,是一種邏輯結構,棧邏輯結構對應的順序存儲結構為順序棧,對應的鏈式存儲結構為鏈棧,循環隊列是順序存儲結構,鏈表是線性表的鏈式存儲結構
用循環鏈表表示隊列,必定有鏈表的頭結點,題目中說鏈表設有尾指針。因此入隊操作在鏈表尾插入,直接插入再尾指針指向的節點后面,時間復雜度是常數級的;出隊操作在鏈表表頭進行,也就是刪除表頭指向的節點,時間復雜度也是常數級的。
在棧中,棧底保持不變,有元素入棧,棧頂指針增加;有元素出棧,棧頂指針減小。在循環隊列中,隊頭指針和隊尾指針的動態變化決定隊列的長度。在循環鏈表中,前一個結點指向后一個結點,而最后一個結點指向頭結點,只有頭結點是固定的。線性鏈表中,由於前一個結點包含下一個結點的指針,尾結點指針為空,要插入刪除元素,只需要改變相應位置的結點指針即可,頭指針和尾指針無法決定鏈表長度。
循環隊列解決的是“假溢出”問題,但是仍然會出現真正的溢出問題。假溢出指的是下標溢出,真溢出指的是空間溢出。
DFS是深度優先搜索,是后進先出,所以需要借助於一個棧來實現。而BFS,也就是廣度優先搜索才是借助一個隊列來實現
循環隊列,其隊頭指針為front,隊尾指針為rear;循環隊列長度為N。其隊內有效長度為?(假設隊頭不存放數據) (rear - front + N) % N
下面數據結構能夠支持隨機的插入和刪除操作、並具有較好的性能的是____。
1,數組是在定義的時候申請一塊連續的內存空間,訪問某個元素只需要通過下標就可以,但是隨機插入和刪除都要移動后面所有的元素,所以,數組肯定不行;
2,鏈表,是非連續的空間,通過指針訪問,所以隨機插入和刪除通過指針之間的操作很方便,但是如果要查詢一個數的時候還是得依次便利,但是題目問的是隨機插入和刪除,所以,鏈表可以;
3,棧,所有的操作都是在棧頂,如果要隨機插入或者刪除某個數也必須依次對其他數就行操作,所以,棧也排除;
4,隊列,通過隊頭和隊尾指針進行讀入數據和刪除數據,如果直接在隊尾添加數據很方便,但是,題目中是隨機,所以,隊列排序;
5,哈希表通過鍵值對操作,只要知道相關的key很容易就行讀取和刪除,插入某個元素也通過key很方便,所以,哈希表肯定可以;
棧的常見應用:瀏覽器歷史紀錄,Android中的最近任務,Activity的啟動模式,CPU中棧的實現,Word自動保存,解析計算式,解析xml/json
循環隊列的相關條件和公式:
隊尾指針是rear,隊頭是front,其中QueueSize為循環隊列的最大長度
1.隊空條件:rear==front
2.隊滿條件:(rear+1) %QueueSIze==front
3.計算隊列長度:(rear-front+QueueSize)%QueueSize
4.入隊:(rear+1)%QueueSize
5.出隊:(front+1)%QueueSize