線性表是一類很常用的資料結構,分為順序表和煉表。其中順序表可以簡單地理解成前面介紹的「陣列」這個概念,接下來我們講解一下鍊錶。
按照正常方式定義乙個陣列時,計算機會從記憶體中取出一塊連續的位址來存放給定長度的陣列;而鍊錶則是由若干個結點組成(每個結點代表乙個元素),而且結點在記憶體中的儲存位置通常是不連續的。除此之外,鍊錶的兩個結點之間一般通過乙個指標來從乙個結點指向另乙個結點,因此鍊錶的結點一般由兩部分組成,即資料域和指標域:
struct node
//補充一點小知識:很多同學老說這個「*」號到底放在哪呢,
//其實放哪都行,放在typename後面挨著也行,放在變數名前面挨著也行。
資料域存放結點要儲存的資料,指標域指向下乙個結點的位址,這樣就會產生從某個結點開始的、由指標鏈結的一條鏈式結構,即鍊錶。而以鍊錶是否存在頭結點,又可以把鍊錶分為帶頭結點的鍊錶和不帶頭結點的鍊錶。頭結點一般稱為head,其資料域data不存放任何內容,而指標域next指向第乙個資料域有內容的結點(一般稱其為第乙個結點)。大部分情況都會採用有頭結點的寫法。
上面我們已經知道如何定義鍊錶的結點型別,接下來我們將如何在每次需要使用新結點時候臨時分配相應大小的記憶體空間給新結點。c語言採用malloc函式,c++採用new運算子。
malloc函式是c語言中stdlib.h標頭檔案下用於申請動態記憶體的函式,其返回型別申請的同變數型別的指標,基本用法如下:
typename* p = (typename*)malloc(sizeof(typename));
//以下是申請乙個int型變數和乙個node型結構體變數為例:
int *p = (int*)malloc(sizeof(int));
node *p = (node*)malloc(sizeof(node));
這個寫法的邏輯是:以需要申請的記憶體空間的大小(即sizeof(int))為malloc函式的引數,這樣malloc函式就會向記憶體申請一塊大小為sizeof(int)的空間,並且返回指向這空間的指標。但是此時這個指標是乙個未確定型別的指標void*,因此需要把它強制轉換為int型指標,因此malloc之前加上(node)。這樣等號右邊就得到乙個int型的指標,並通過賦值等號把這個指標賦給node型的指標變數p,就成功申請了一塊node型別大小的記憶體空間,即乙個node型的結構體變數,並通過指標p來訪問它,如果申請失敗了,則會返回空指標null。
一般來說,只是申請乙個鍊錶的結點是不會失敗的,失敗一般發生在使用malloc申請了較大的動態陣列,即
這種情況malloc會返回空指標null並賦值給p。
記憶體洩露是指使用malloc與new開闢出來的記憶體空間在使用過後沒有釋放,導致其在程式結束之前始終佔據該記憶體空間,這在一些大的程式中很容易導致記憶體消耗過快以至於最後無記憶體可分配。在使用完malloc與new開闢出來的空間後必須將其釋放。
(1)free函式
free函式是對應malloc函式的,同樣是在stdlib.h下。只需要在free的引數中填寫需要釋放的記憶體空間的指標變數(假設為p)即可:
free(p);
free函式主要實現了兩個效果:釋放指標變數p所指向的記憶體空間:將指標變數p指向空位址null。由此可見,在free函式執行之後,指標變數p本身並沒有消失,只不過讓他指向了空位址null,但是他原來指向的記憶體確實是被釋放了的。 資料結構之鍊錶 一
線性表分為順序儲存結構和鏈式儲存結構2種。順序儲存結構的特點 任何乙個元素都可以進行隨即訪問,訪問速度高。但不適合瀕繁的插入和刪除操作。鏈式儲存結構 鍊錶 不可以隨即訪問元素。但適合頻繁的插入和刪除操作。乙個靜態鍊錶的例子 include struct node typedef struct nod...
資料結構之鍊錶(一)
很多人,一接觸到資料結構就難懂,就說有難度,還有就說,鍊錶有什麼用?今天我就詳細的說下,這個鍊錶有什麼用。一 鍊錶介紹 1 鍊錶有位址不連續的結點序列,必須通過指標相互連線。2 鍊錶的分類 1 單向線性鍊錶 每個節點中除了儲存資料結構內容以外,還需要儲存指向下乙個節點的指標,叫做後指標。最後乙個節點...
資料結構之鍊錶 一
線性表分為順序儲存結構和鏈式儲存結構2種。順序儲存結構的特點 任何乙個元素都可以進行隨即訪問,訪問速度高。但不適合瀕繁的插入和刪除操作。鏈式儲存結構 鍊錶 不可以隨即訪問元素。但適合頻繁的插入和刪除操作。乙個靜態鍊錶的例子 include struct node typedef struct nod...