1. 程式人生 > >數據結構:線性表

數據結構:線性表

spa eat solid endif 數據 png tex 只有一個 pre

線性表設計與實現

線性表基本概念

線性表定義

線性表(List)是零個或多個數據元素的集合

線性表中的數據元素之間是有順序的

線性表中的數據元素個數是有限的

線性表中的數據元素的類型必須相同

技術分享圖片

數學定義

線性表是具有相同類型的 n( ≥ 0)個數據元素的有限序列(a1, a2, …, an)ai是表項,n 是表長度。

性質

a0為線性表的第一個元素,只有一個後繼

an為線性表的最後一個元素,只有一個前驅

除a0和an外的其它元素ai,既有前驅,又有後繼
線性表能夠逐項訪問和順序存取

練習

下面的關系中可以用線性表描述的是

A.班級中同學的友誼關系

B.公司中的上下級關系

C.冬天圖書館排隊占座關系

D.花名冊上名字之間的關系

線性表的操作

創建線性表

銷毀線性表

清空線性表

將元素插入線性表

將元素從線性表中刪除

獲取線性表中某個位置的元素

獲取線性表的長度

線性表在程序中表現為一種特殊的數據類型

線性表的操作在程序中的表現為一組函數

C語言描述=====》線性表的設計與實現

#ifndef _WBM_LIST_H_

#define _WBM_LIST_H_

typedef void List;

typedef void ListNode;

//創建並且返回一個空的線性表

List* LinkList_Create();

//銷毀一個線性表list

void List_Destroy(List* list);

//將一個線性表list中的所有元素清空, 線性表回到創建時的初始狀態

void List_Clear(List* list);

//返回一個線性表list中的所有元素個數

int List_Length(List* list);

//向一個線性表list的pos位置處插入新元素node

int List_Insert(List* list, ListNode* node, int pos);

//獲取一個線性表list的pos位置處的元素

ListNode* List_Get(List* list, int pos);

//刪除一個線性表list的pos位置處的元素 返回值為被刪除的元素,NULL表示刪除失敗

ListNode* List_Delete(List* list, int pos);

#endif

線性表的順序存儲結構

1、基本概念

技術分享圖片

2、設計與實現

插入元素算法

判斷線性表是否合法

判斷插入位置是否合法

把最後一個元素到插入位置的元素後移一個位置

將新元素插入

線性表長度加1

獲取元素操作

判斷線性表是否合法

判斷位置是否合法

直接通過數組下標的方式獲取元素

刪除元素算法

判斷線性表是否合法

判斷刪除位置是否合法

將元素取出

將刪除位置後的元素分別向前移動一個位置

線性表長度減1

3、優點和缺點

優點:

無需為線性表中的邏輯關系增加額外的空間

可以快速的獲取表中合法位置的元素

缺點:

插入和刪除操作需要移動大量元素

當線性表長度變化較大時難以確定存儲空間的容量

線性表的鏈式存儲

1、基本概念

鏈式存儲定義

為了表示每個數據元素與其直接後繼元素之間的邏輯關系,每個元素除了存儲本身的信息外,還需要存儲指示其直接後繼的信息。

技術分享圖片

技術分享圖片

表頭結點

鏈表中的第一個結點,包含指向第一個數據元素的指針以及鏈表自身的一些信息

數據結點

鏈表中代表數據元素的結點,包含指向下一個數據元素的指針和數據元素的信息

尾結點

鏈表中的最後一個數據結點,其下一元素指針為空,表示無後繼。

2、設計與實現

在C語言中可以用結構體來定義鏈表中的指針域

鏈表中的表頭結點也可以用結構體實現

技術分享圖片

技術分享圖片

帶頭結點、位置從0的單鏈表

返回鏈表中第3個位置處,元素的值

LinkListNode* LinkList_Get(LinkList* list, int pos)

{

int i = 0;

TLinkList *tList = (TLinkList *)list;

LinkListNode *current = NULL;

LinkListNode *ret = NULL;

if (list==NULL ||pos<0 || pos>=tList->length)

{

return NULL;

}

current = (LinkListNode *)tList;

for (i=0; i<pos; i++)

{

current = current->next;

}

ret = current->next;

return ret ;

}

返回第三個位置的

移動pos次以後,當前指針指向哪裏?

答案:指向位置2,所以需要返回 ret = current->next;

備註:

循環遍歷時, 遍歷第1次,指向位置0

遍歷第2次,指向位置1

遍歷第3次,指向位置2

遍歷第n次,指向位置n-1;

所以如果想返回位置n的元素的值,需要怎麽做

ret = current->next;

此問題是:指向頭結點的指針移動n次 和 第n個元素之間的關系?

刪除元素

技術分享圖片

3、優點和缺點

優點:

無需一次性定制鏈表的容量

插入和刪除操作無需移動數據元素

缺點:

數據元素必須保存後繼元素的位置信息

獲取指定數據的元素操作需要順序訪問之前的元素

循環鏈表

1、基本概念

循環鏈表的定義:將單鏈表中最後一個數據元素的next指針指向第一個元素

技術分享圖片

循環鏈表擁有單鏈表的所有操作

創建鏈表

銷毀鏈表

獲取鏈表長度

清空鏈表

獲取第pos個元素操作

插入元素到位置pos

刪除位置pos處的元素

新增功能:遊標的定義

在循環鏈表中可以定義一個"當前"指針,這個指針通常稱為遊標,可以通過這個遊標來遍歷鏈表中的所有元素。

技術分享圖片

循環鏈表新操作

獲取當前遊標指向的數據元素

將遊標重置指向鏈表中的第一個數據元素

將遊標移動指向到鏈表中的下一個數據元素

直接指定刪除鏈表中的某個數據元素

CircleListNode* CircleList_DeleteNode(CircleList* list, CircleListNode* node);

CircleListNode* CircleList_Reset(CircleList* list);

CircleListNode* CircleList_Current(CircleList* list);

CircleListNode* CircleList_Next(CircleList* list);

2、設計與實現

插入元素的分析

  1. 普通位置插入元素
  2. 添加第一個元素(第一次插入元素)
  3. 最後一個位置插入元素
  4. 第一個位置插入元素

在第一個位置插入

技術分享圖片

技術分享圖片

刪除節點

技術分享圖片

3、優點和缺點

優點:功能強了。

循環鏈表只是在單鏈表的基礎上做了一個加強

循環鏈表可以完全取代單鏈表的使用

循環鏈表的Next和Current操作可以高效的遍歷鏈表中的所有元素

缺點:

代碼復雜度提高了

約瑟夫問題-循環鏈表典型應用

n 個人圍成一個圓圈,首先第 1 個人從 1 開始一個人一個人順時針報數,報到第 m 個人,令其出列。然後再從下一 個人開始從 1 順時針報數,報到第 m 個人,再令其出列,…,如此下去,求出列順序。

技術分享圖片

雙向鏈表

1、基本概念

單鏈表的結點都只有一個指向下一個結點的指針

單鏈表的數據元素無法直接訪問其前驅元素

逆序訪問單鏈表中的元素是極其耗時的操作!

len = LinkList_Length(list);

for (i=len-1; len>=0; i++) //O(n)

{

LinkListNode *p = LinkList_Get(list, i); //O(n)

//訪問數據元素p中的元素

//

}

雙向鏈表的定義

在單鏈表的結點中增加一個指向其前驅的pre指針

技術分享圖片

雙向鏈表擁有單鏈表的所有操作

創建鏈表

銷毀鏈表

獲取鏈表長度

清空鏈表

獲取第pos個元素操作

插入元素到位置pos

刪除位置pos處的元素

2、設計與實現

插入操作

技術分享圖片

刪除操作

技術分享圖片

雙向鏈表的新操作

獲取當前遊標指向的數據元素

將遊標重置指向鏈表中的第一個數據元素

將遊標移動指向到鏈表中的下一個數據元素

將遊標移動指向到鏈表中的上一個數據元素

直接指定刪除鏈表中的某個數據元素

DLinkListNode* DLinkList_DeleteNode(DLinkList* list, DLinkListNode* node);

DLinkListNode* DLinkList_Reset(DLinkList* list);

DLinkListNode* DLinkList_Current(DLinkList* list);

DLinkListNode* DLinkList_Next(DLinkList* list);

DLinkListNode* DLinkList_Pre(DLinkList* list);

//大家一定要註意:教科書不會告訴你 項目上如何用;哪些點是項目的重點;

做一個企業級的財富庫,完成你人生開發經驗的積累,是我們的學習重點,要註意!

3、優點和缺點

優點:雙向鏈表在單鏈表的基礎上增加了指向前驅的指針

功能上雙向鏈表可以完全取代單鏈表的使用

循環鏈表的Next,Pre和Current操作可以高效的遍歷鏈表中的所有元素

缺點:代碼復雜

數據結構:線性表