用一段連續的儲存單元一次儲存線性表的資料元素。
結構**:
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 組成的有限序列。維基百科 線性表是乙個...