大話資料結構學習之(二) 線性表

2021-06-26 07:43:45 字數 4036 閱讀 4711

用一段連續的儲存單元一次儲存線性表的資料元素。

結構**:

const int maxsize = 20; // 儲存空間初始分配量

typedef int elemtype; // elemtype型別根據實際情況而定,這裡假設為int

typedef struct

sqlist;

這裡,我們發現描述順序儲存結構需要三個屬性:

陣列長度是存放線性表儲存空間的長度,線性表長度是線性表中資料元素的個數。任意時刻線性表的長度應小於等於陣列長度。

其訪問效能為o(1),通常把具有這一特點的儲存結構成為隨機儲存結構。

// 初始條件:順序線性表l已經存在,1<=i<=listlength(l)

// 操作結果:在l中第i個位置之前插入新的資料元素e,l長度加1

status listinsert(sqlist *l, int i, elemtype e)

} l->data[i-1] = e;

l->length++;

return ok;

}

// 初始條件:順序線性表l已經存在,1<=i<=listlength(l)

// 操作結果:刪除在l中第i個位置之前的資料元素e,l長度減1

status listdelete(sqlist *l, int i, elemtype *e)

} l->length--;

return ok;

}

複雜度最好情況o(1),最差情況o(n),平均複雜度為o((n-1)/2) = o(n)。

這說明,它比較適合於元素個數不太變化,而更多是訪問資料的應用。

優點: 缺點:

鍊錶中第乙個結點的儲存位置叫做

頭指標。線性鍊錶的最後乙個結點指標為「空」(通常用null或「^」符號表示)。

有時,我們為了更加方便的對鍊錶進行操作,會在單鏈表的第乙個結點前附設乙個結點,稱為

頭結點。頭結點的資料域可以不儲存任何資訊,也可以儲存如線性表長度等附加資訊,頭結點的指標域儲存指向第乙個結點的指標。

頭結點與頭指標的異同:

頭指標:

頭結點:

// 線性表的單鏈表儲存結構

typedef struct node

node;

typedef struct node *linklist; // 定義linklist

// 初始條件:順序線性表l已經存在,1<=i<=listlength(l)

// 操作結果:用e返回l中第i個資料元素的值

status getelem(linklist l, int i, elemtype *e)

if (!p || j>i)

*e = p->data; // d取第i個元素的資料

return ok;

}

說白了,就是從頭開始找,直到第i個元素為止。時間複雜度取決於i的位置,i=1時不需要遍歷,而i=n時,則遍歷n-1次才可以。

// 初始條件:順序線性表l已經存在,1<=i<=listlength(l)

// 操作結果:在l中第i個位置之前插入新的資料元素e,l長度加1

status listinsert(linklist *l, int i, elemtype e)

if (!p || j>i)

s = (linklist)malloc(sizeof(node));// 生成新結點

s->data = e;

s->next = p->next;// 將p的後繼結點賦值給s的後繼

p->next = s; // 將s賦值給p的後繼

return ok;

}

對於單鏈表的表頭和表尾的特殊情況,操作是相同的。

// 初始條件:順序線性表l已經存在,1<=i<=listlength(l)

// 操作結果:刪除在l中第i個位置之前的資料元素e,l長度減1

status listdelete(linklist *l, int i, elemtype *e)

if (!(p->next) || j>i)

q = p->next;

p->next = q->next;

*e = q->data; // 將q結點中的資料給e

free(q); // **此結點

return ok;

}

對插入刪除資料越頻繁的操作,單鏈表的效率優勢就越明顯。

建立單鏈表的過程就是乙個動態生成鍊錶的過程,即從「空表」的初始狀態起,依次建立各個元素結點,並逐個插入鍊錶。

// 隨機產生n個元素的值,建立帶表頭結點的單鏈線性表l(頭插法)

void createlisthead(linklist *l, int n)

}

// 隨機產生n個元素的值,建立帶表頭結點的單鏈線性表l(尾插法)

void createlisttail(linklist *l, int n)

r->next = null;

}

// 初始條件:順序線性表l已經存在

// 操作結果:將l重置為空表

status clearlist(linklist *l)

(*l)->next = null;// 頭結點指標域為空

return ok;

}

要知道p是乙個結點,除了資料域還有指標域,free(p)是對整個結點進行刪除和記憶體釋放工作。所以如果程式中直接像下面這樣寫會出問題的(p的位址域已經被釋放)

free(p);
p = p->next;
對於非空的迴圈鍊錶如下:

其實迴圈鍊錶和單鏈表的主要差異就在於迴圈的判斷條件上,原來是判斷p->next是否為空,現在是它不等於頭結點,則迴圈結束。

雙向鍊錶是在單鏈表的每個結點中,再設定乙個指向其前驅結點的指標域。

// 線性表的雙向鍊錶儲存結構

typedef struct dulnode

dulnode, *dulinklist;

對於雙向鍊錶中的乙個結點p,它的後繼的前驅,以及前驅的後繼都是自己。

插入操作時,並不複雜,但是順序很重要,不能寫反了。

s->prior = p; // 把p賦值給s的前驅,如圖中的1

s->next = p->next; // 把p->next賦值給s的後繼,如圖中2

p->next->prior = s; // 把s賦值給p->next的前驅,如圖中3

p->next = s; // 把s賦值給p的後繼,如圖中的4

p->prior->next = p->next; 

p->next->prior = p->prior;

free(p);

資料結構(二) 線性表

線性表是最簡單最常用的資料結構,是一種典型的線性儲存結構。定義 線性表是由n n 0 個資料元素 結點 a1 a 2 an 組成的有限序列。n為表的長度。當n 0,為 空表 n 0時,為 a1,a 2,an 邏輯特徵 非空的線性表只有乙個頭結點,也只有乙個終結點,頭結點只有乙個直接後繼結點,而沒有直...

資料結構學習 線性表

線性表一般分為順序結構和鏈式結構。順序表裡面元素的位址是連續的,如陣列 鍊錶裡面節點的位址不是連續的,是通過指標連起來的,如單鏈表 順序結構 優點 易於查詢,索引快 list n 這樣的操作,o 1 複雜度。缺點 擴充套件性弱,不易刪除 插入,這兩項操作均是o n 的時間複雜度 鍊錶結構 優點 擴充...

資料結構學習 線性表

考試前複習下資料結構,把一些知識點整理在這!主要參考了殷人昆主編的 資料結構 用物件導向方法與c 語言描述 這本書,以及中山大學劉聰老師的課件內容!鍊錶雙鏈表 線性表 linear list 是由n n 0 個資料元素 結點 a 0 a 1 a 2 a n 1 組成的有限序列。維基百科 線性表是乙個...