鏈表是一種常見(jiàn)的基礎(chǔ)數(shù)據(jù)結(jié)構(gòu),結(jié)構(gòu)體指針在這里得到了充分的利用。鏈表可以動(dòng)態(tài)的進(jìn)行存儲(chǔ)分配,也就是說(shuō),鏈表是一個(gè)功能極為強(qiáng)大的數(shù)組,他可以在節(jié)點(diǎn)中定義多種數(shù)據(jù)類型,還可以根據(jù)需要隨意增添,刪除,插入節(jié)點(diǎn)。鏈表都有一個(gè)頭指針,一般以head來(lái)表示,存放的是一個(gè)地址。鏈表中的節(jié)點(diǎn)分為兩類,頭結(jié)點(diǎn)和一般節(jié)點(diǎn),頭結(jié)點(diǎn)是沒(méi)有數(shù)據(jù)域的。鏈表中每個(gè)節(jié)點(diǎn)都分為兩部分,一個(gè)數(shù)據(jù)域,一個(gè)是指針域。說(shuō)到這里你應(yīng)該就明白了,鏈表就如同車鏈子一樣,head指向第一個(gè)元素:第一個(gè)元素又指向第二個(gè)元素;……,直到最后一個(gè)元素,該元素不再指向其它元素,它稱為“表尾”,它的地址部分放一個(gè)“NULL”(表示“空地址”),鏈表到此結(jié)束。
作為有強(qiáng)大功能的鏈表,對(duì)他的操作當(dāng)然有許多,比如:鏈表的創(chuàng)建,修改,刪除,插入,輸出,排序,反序,清空鏈表的元素,求鏈表的長(zhǎng)度等等。
初學(xué)鏈表,一般從單向鏈表開(kāi)始
--->NULL
head
這是一個(gè)空鏈表。
---->[p1]---->[p2]...---->[pn]---->[NULL]
head p1->next p2->next pn->next
有n個(gè)節(jié)點(diǎn)的鏈表。
創(chuàng)建鏈表
typedef struct student{
int score;
struct student *next;
} LinkList;
一般創(chuàng)建鏈表我們都用typedef struct,因?yàn)檫@樣定義結(jié)構(gòu)體變量時(shí),我們就可以直接可以用LinkList *a;定義結(jié)構(gòu)體類型變量了。
初始化一個(gè)鏈表,n為鏈表節(jié)點(diǎn)個(gè)數(shù)。
LinkList *creat(int n){
LinkList *head, *node, *end;//定義頭節(jié)點(diǎn),普通節(jié)點(diǎn),尾部節(jié)點(diǎn);
head = (LinkList*)malloc(sizeof(LinkList));//分配地址
end = head; //若是空鏈表則頭尾節(jié)點(diǎn)一樣
for (int i = 0; i < n; i++) {
node = (LinkList*)malloc(sizeof(LinkList));
scanf("%d", &node->score);
end->next = node;
end = node;
}
end->next = NULL;//結(jié)束創(chuàng)建
return head;
}
修改鏈表節(jié)點(diǎn)值
修改鏈表節(jié)點(diǎn)值很簡(jiǎn)單。下面是一個(gè)傳入鏈表和要修改的節(jié)點(diǎn),來(lái)修改值的函數(shù)。
void change(LinkList *list,int n) {//n為第n個(gè)節(jié)點(diǎn)
LinkList *t = list;
int i = 0;
while (i < n && t != NULL) {
t = t->next;
i++;
}
if (t != NULL) {
puts("輸入要修改的值");
scanf("%d", &t->score);
}
else {
puts("節(jié)點(diǎn)不存在");
}
}
刪除鏈表節(jié)點(diǎn)
刪除鏈表的元素也就是把前節(jié)點(diǎn)的指針域越過(guò)要?jiǎng)h除的節(jié)點(diǎn)指向下下個(gè)節(jié)點(diǎn)。即:p->next = q->next;然后放出q節(jié)點(diǎn)的空間,即free(q);
void delet(LinkList *list, int n) {
LinkList *t = list, *in;
int i = 0;
while (i < n && t != NULL) {
in = t;
t = t->next;
i++;
}
if (t != NULL) {
in->next = t->next;
free(t);
}
else {
puts("節(jié)點(diǎn)不存在");
}
}
插入鏈表節(jié)點(diǎn)
我們可以看出來(lái),插入節(jié)點(diǎn)就是用插入前節(jié)點(diǎn)的指針域鏈接上插入節(jié)點(diǎn)的數(shù)據(jù)域,再把插入節(jié)點(diǎn)的指針域鏈接上插入后節(jié)點(diǎn)的數(shù)據(jù)域。根據(jù)圖,插入節(jié)點(diǎn)也就是:e->next = head->next; head->next = e;
增加鏈表節(jié)點(diǎn)用到了兩個(gè)結(jié)構(gòu)體指針和一個(gè)int數(shù)據(jù)。
void insert(LinkList *list, int n) {
LinkList *t = list, *in;
int i = 0;
while (i < n && t != NULL) {
t = t->next;
i++;
}
if (t != NULL) {
in = (LinkList*)malloc(sizeof(LinkList));
puts("輸入要插入的值");
scanf("%d", &in->score);
in->next = t->next;//填充in節(jié)點(diǎn)的指針域,也就是說(shuō)把in的指針域指向t的下一個(gè)節(jié)點(diǎn)
t->next = in;//填充t節(jié)點(diǎn)的指針域,把t的指針域重新指向in
}
else {
puts("節(jié)點(diǎn)不存在");
}
}
輸出鏈表
輸出鏈表很簡(jiǎn)單,邊遍歷邊輸出就行了。
while (h->next != NULL) {
h = h->next;
printf("%d ", h->score);
}
聯(lián)系客服