邏輯結構上乙個挨著乙個的資料,在實際儲存中,並沒有像順序表那樣也相互緊挨著,恰恰相反,資料隨機分布在記憶體的各個位置,這種儲存結構稱為線性表的鏈式儲存。
由於分散儲存,為了能夠體現出資料元素之間的邏輯關係,每個資料元素在儲存的同時,要配備乙個指標,用於指向它的直接後繼元素,即每乙個資料元素都指向下乙個資料元素(最後乙個指向null(空))。
線性表的鏈式儲存結構生成的表,稱作鍊錶。
連表中資料元素的構成:
每個元素本身有兩個部分組成
1,本身的資訊,稱為資料域;
2,指向直接後繼的指標,稱為指標域。
由這兩部分資訊組成資料元素的儲存結構,稱之為節點。n個節點通過指標域相互鏈結,組成乙個鍊錶。
由於每個節點中只包含乙個指標域,生成的鍊錶又稱為線性鍊錶或單鏈表。
鍊錶中存放的不是基本資料型別,需要用結構體實現自定義:
typedef struct linklink;
頭結點:有時,在鍊錶的第乙個節點之前會額外增設乙個結點,結點的資料域一般不存放資料(有些情況下也可以存放鍊錶的長度等資訊),次節點被稱為頭結點。
若頭結點的指標域為空(null),表明鍊錶時空表。頭結點對於鍊錶來說,不是必須的,在處理某些問題時,給鍊錶新增頭會使問題變得簡單。
首元結點:連表中第乙個元素所在的結點,它是頭結點後邊的第乙個結點。
頭指標:永遠指向鍊錶中第乙個結點的位置(如果鍊錶有頭結點,頭指標指向頭結點;否則,指標指向首元結點)。
頭結點和頭指標的區別:頭指標是乙個指標,頭指標指向鍊錶的頭結點或者首元結點;頭結點是乙個實際存在的結點,它包含有資料域和指標域。兩者在程式中的直接體現就是:頭指標只是宣告而沒有分配儲存空間,頭結點進行了宣告並分配了乙個結點的實際物理記憶體。
鍊錶中可以沒有頭結點,但是不能沒有頭指標!
鍊錶的建立和遍歷
初始化鍊錶首先要做的就是建立鍊錶的頭結點或者首元結點。建立的同時,要保證有乙個指標永遠指向的是鍊錶的表頭,這樣做不至於丟失鍊錶。
例如建立乙個鍊錶(1,2,3,4):
link *initlink()
return p;
}
ps:temp先是指向頭結點,1,然後把第乙個資料元素結點的位址(a)給頭結點的next指標,然後tmep指向第乙個資料元素結點,2,然後把第二個資料元素結點的位址給temp的next指標,然後temp指標指向第二個資料元素的結點。
連表中查詢某節點
一般情況下,鍊錶只能通過頭結點或者頭指標進行訪問,所以實現查詢某結點最常用的方法就是對鍊錶中的結點進行逐個遍歷
int selectelem(link *p, int elem)
i++;
}return -1;
}
鍊錶中更改某節點中的資料域
連表中修改結點的資料域,通過遍歷的方法找到該結點,然後直接更改資料域的值。
//更新函式,其中add表示更改結點在鍊錶中的位置,newelem為新的資料域的值
link* amendelem(link*p, int add, int enwelem)
temp->elem = newelem;
return p;
}
向鍊錶中插入結點
鍊錶中插入結點,根據插入位置的不同,分為三種
1,插入到鍊錶的首部,也就是頭結點和首元結點中間;
2,插入到鍊錶中間的某個位置;
3,插入到鍊錶最末端;
思路:在做插入操作時,首先要找到插入位置的上乙個節點a,也就是找到結點a,相應的結點b可以通過結點a的next指標表示,這樣,先進行1:將新結點的next指標指向插入位置後的結點;2:將插入位置前的結點的next指標指向插入結點;實現過程不需要新增其他輔助指標
link* insertelem(link *p, int elem, int add)
//建立插入結點c
link*c=(link*)malloc(sizeof(link));
c->elem=elem;
//向鍊錶中插入結點
c->next=temp->next;
temp->next=c;
return p;
}
tip:首先要保證插入位置的可行性,如果原本只有5個結點,插入位置可以選擇的範圍為:1-6,如果超過6,本身不具本任何意義,程式提示插入位置無效。
從鍊錶中刪除結點
當需要從鍊錶中刪除某乙個結點時,需要進行兩步操做:
1,將結點從鍊錶中摘出來
2,手動釋放掉結點,**被結點占用的記憶體空間;
使用malloc函式申請的空間,一定要注意手動free掉。否則在程式執行的整個過程中,申請的記憶體空間不會自己釋放(只有當整個程式執行完了以後,這塊記憶體才會被**),造成記憶體洩漏,別把它當成小問題。
link *delelem(link*p, int add)
link*del = temp->next;//單獨設定乙個指標指向被刪除的結點,以防丟失
temp->next=temp->next->next;//刪除某個結點的方法就是更改前乙個結點的指標域
free(del);//手動釋放該結點,防止記憶體洩漏
return p;
}
總結:
線性表的鏈式儲存相比較於順序儲存,有兩大優勢:
1,鏈式儲存的資料元素在物理結構沒有限制,當記憶體空間中沒有足夠大的連續記憶體空間供順序表使用時,可能使用鍊錶能解決問題(鍊錶每次申請的都是單個資料元素的儲存空間,可以利用上一些記憶體碎片)
2,鍊錶中結點之間採用指標進行連線,當對鍊錶中的資料元素實行插入或者刪除操作時,只需要改變指標的指向,無需像順序表那樣移動插入或者刪除位置的後續元素,簡單快捷。
鍊錶和順序表相比,不足之處在於,當做遍歷操作時,由於鍊錶中結點的物理位置不相鄰,使得計算機查詢起來相比較順序表,速度要慢。
線性表的鏈式儲存 單鏈表
forward list creat 3 頭插法 return head 尾插法建表 forward list creat 1 if rear null 對於非空表,將尾結點的下乙個結點置空 rear next null return head 尾插法建表,包含頭結點 forward list cr...
線性表的鏈式儲存 單鏈表的實現
1,完成鏈式儲存結構線性表的實現 2,linklist 設計要點 1,類模板,通過頭結點訪問後繼結點 2,定義內部結點型別 node,用於描述資料域和指標域 3,實現線性表的關鍵操作 增刪查等 3,鍊錶的定義 4,linklist 鍊錶的實現 1 ifndef linklist h 2 define...
線性表之鏈式儲存 單向迴圈鍊錶
單向迴圈線性表 也是通過結點的形式在儲存器中進行儲存,結點包括資料域和指標域,邏輯上相鄰的兩個結點在物理上不一定相鄰,單向迴圈鏈式儲存的線性表,定義了乙個唯一的頭結點,頭結點的資料域是儲存資料的,指標域next指標指向下乙個結點,也就是開始結點,定義了乙個尾結點,尾結點的next指向頭結點,資料域是...