日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

c语言中头结点不为零怎么写,C语言不带表头结点的单链表操作

發(fā)布時間:2025/3/19 编程问答 46 豆豆
生活随笔 收集整理的這篇文章主要介紹了 c语言中头结点不为零怎么写,C语言不带表头结点的单链表操作 小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個參考.

什么是鏈表

簡單理解為鏈表的功能與數(shù)組功能相似用來存儲數(shù)據(jù),鏈表作為一種基本的數(shù)據(jù)結(jié)構(gòu)在程序開發(fā)過程當中經(jīng)常會使用到。對C語言來說鏈表的實現(xiàn)主要依靠結(jié)構(gòu)體(可以存儲多種數(shù)據(jù)類型)和指針,所以本文相關(guān)內(nèi)容和程序需要有C語言當中指針和結(jié)構(gòu)體的基礎(chǔ)。

為什么使用鏈表

1、解決數(shù)組無法存儲多種數(shù)據(jù)類型的問題。

2、解決數(shù)組中,元素個數(shù)無法改變的限制。

3、數(shù)組移動元素的過程中,要對元素進行大范圍的移動,很耗時間,效率也不高。

鏈表的組成

1、鏈表由節(jié)點組成。

2、節(jié)點由值域與指針域組成。

3、還需要一個頭指針指向鏈表(例如一個指針指向一個數(shù)組,那么數(shù)組名也可以代表此數(shù)組的首地址)

4、鏈表的基本表示

struct node //表示圖片中的體

{

int num;

char a;

struct node *next; //指向下一個相同數(shù)據(jù)類型的結(jié)構(gòu)體,next存放下一個結(jié)點的地址

}

> head頭指針指向頭結(jié)點,其中頭結(jié)點的next指針指向下一個節(jié)點的頭,一次類推直到最后一個節(jié)點的尾指針指向NULL(空指針)時離鏈表結(jié)束。

(這里的體是結(jié)構(gòu)體類型,next是指向下一個結(jié)點的指針,結(jié)點的組成:數(shù)據(jù)域(體是數(shù)據(jù)域的一種體現(xiàn))+(指針域) )

鏈表的特點

1、鏈表結(jié)點可以連續(xù),可以不連續(xù)存儲。

2、結(jié)點的邏輯順序與物理順序可以不一致。

3、表可擴充。

邏輯順序與物理順序的理解

可以使用的存儲空間

解釋:各個結(jié)點的物理存儲位置可能不是連續(xù)的,a0后面是a2而不是a1,但是每個結(jié)點的尾地址都是按照邏輯順序指向下一個結(jié)點的。(意思就是說我有10個抽屜,每個抽屜編號1~10,但是這10個抽屜不是按順序擺放,將撲克牌A到10一次按抽屜順序放入10個抽屜里,每次取按順序取出,例如第一個抽屜在第1層,里面是A,接下來要去2但是存放2的抽屜在第5層因此要去第5層取2)

怎么插入一個節(jié)點

在頭結(jié)點的后面插入一個節(jié)點

插入一個中間節(jié)點

在頭節(jié)點前面插入節(jié)點(頭插)

尾插

1、

將一個新的結(jié)點插入到最后一個節(jié)點的后面,先將前一個尾結(jié)點的地址指向新結(jié)點的地址P,然后再將新結(jié)點的指針域改成NULL。

2、

頭插入:新建一個結(jié)點他的指針域指向頭結(jié)點的頭地址,修改之后在將鏈表的頭地址指向新建結(jié)點的地址這樣新建結(jié)點就成為鏈表新的頭節(jié)點

**

對于鏈表中&head,一級指針,二級指針的總結(jié)

分析:

1,只要是修改頭指針則必須傳遞頭指針的地址,否則傳遞頭指針值即可(即頭指針本身)。這與普通變量類似,當需要修改普通變量的值,需傳遞其地址,否則傳遞普通變量的值即可(即這個變量的拷貝)。使用二級指針,很方便就修改了傳入的結(jié)點一級指針的值。 如果用一級指針,則只能通過指針修改指針所指內(nèi)容,卻無法修改指針的值,也就是指針所指的內(nèi)存塊。所以創(chuàng)建鏈表和銷毀鏈表需要二級指針或者一級指針引用。

2,不需要修改頭指針的地方用一級指針就可以了,比如插入,刪除,遍歷,清空結(jié)點。假如頭指針是L,則對L->next 及之后的結(jié)點指針只需要傳遞一級指針。

3,比如一個結(jié)點p,在函數(shù)里要修改p的指向就要用二級指針,如果只是修改p的next指向則用一級指針就可以了

~~~*以下代碼均是對于無表頭結(jié)點的操作*~

**

寫頭插時應該先想好代碼的思路:

創(chuàng)建結(jié)點元素

創(chuàng)建空鏈表

創(chuàng)建結(jié)點

插入節(jié)點函數(shù)

編譯鏈表

//創(chuàng)建結(jié)點元素

//創(chuàng)建空鏈表

//創(chuàng)建結(jié)點

//插入節(jié)點函數(shù)

//編譯鏈表

#include #includestruct node //構(gòu)思結(jié)點元素

{

int num;

char name[20];

int age;

struct node * next;

};

typedef struct node Node;

typedef Node * Link;

void creat_list(Link * head) //創(chuàng)建鏈表初始化為空表

{

*head = NULL;

}

void is_malloc_ok(Link new_node) //判斷創(chuàng)建的結(jié)點是否成功分配了空間

{

if(NULL == new_node)

{

printf("malloc error!\n");

exit(-1);

}

}

void creat_new_node(Link * new_node)

{

*new_node = (Link)malloc(sizeof(Node));

is_malloc_ok(*new_node);

}

void display(Link head) //打印鏈表

{

Link p;

p = head;

if(NULL == head)

{

printf("Link is empty!\n");

return;

}

while(NULL != p)

{

printf("%d\n",p->num);

p = p->next;

}

}

void insert_node_head(Link * head,Link new_node)

{

new_node->next = *head; //通過圖2進行理解這里的地址轉(zhuǎn)換

*head = new_node;

}

int main()

{

int i = 0;

Link head = NULL; //初始化避野指針

Link new_node = NULL;

creat_list(&head); //**head是頭地址,對于鏈表創(chuàng)建是對于地址的操作,

因為鏈表名本身代表鏈表首地址,因此在調(diào)用函數(shù)操作傳入一個二階地址,

通過解引用(*head)來操作指針head**

for(i=0; i < 10; i++)

{

creat_new_node(&new_node);

new_node->num = i + 1;

insert_node_head(&head,new_node);

}

display(head);

return 0;

}

寫尾插法的代碼

void insert_node_tail(Link * head,Link new_node)

{

Link p; //尾插需要找到上一個結(jié)點的尾指針,因此需要一個變量定義此指針

p = *head;

if(NULL == *head) //鏈表為空時先插入第一個結(jié)點

{

*head = new_node;

new_node->next = NULL;

}

else //當P不為空時插入第二個結(jié)點

{

while(NULL != p->next)

{

p = p->next;

}

p->next = new_node; //尾插讓新結(jié)點的next都是NULL,頭指向上一個結(jié)點

new_node->next = NULL;

}

**

總結(jié)

由上面的例子以及比較,我們可以看見:

1、頭插法相對簡便,但插入的數(shù)據(jù)與插入的順序相反;

2、尾插法操作相對復雜,但插入的數(shù)據(jù)與插入順序相同。

**

隨機數(shù)倒敘排列

int insert_node_mid_sort(Link * head,Link new_node)

{

Link p,q;

p = q = *head;

if(NULL == *head) //空表時將第一個結(jié)點插入此時頭結(jié)點地址不為空

{

*head = new_node;

new_node->next = NULL;

}

else if((*head)->num > new_node->num) //當結(jié)點的num>頭結(jié)點時將他插入到頭結(jié)點前面

{

new_node->next = *head;

*head = new_node;

}

else

{

while(p != NULL && p->num < new_node->num) //參考下圖分析代碼 (&&有一個不滿足條件時就跳出代碼執(zhí)行下面的代碼)

{

q = p;

p = p->next;

}

q->next = new_node;

new_node->next = p;

}

}

只需要將6的頭插入到5的尾,6的尾巴插入到7的頭就可以了。

while(p != NULL && p->num < new_node->num)

因為此時鏈表中已經(jīng)有了結(jié)點,所以P不是NULL,切有num,此時5<6,

p,q,head,地址相同,此時p指向下一個結(jié)點

q = p;

p = p->next;

q->next = new_node;

new_node->next = p;

此時將new_node的頭地址,尾地址互換插入到鏈表中去,

**

將一個num添加到一個結(jié)點的前面

void insert_node_mid_front(Link * head,Link new_node,int loc)

{

Link p,q;

p = q = *head;

if((*head)->num == loc)

{

new_node->next = *head;

*head = new_node;

}

else

{

while(p != NULL && p->num != loc)

{

q = p;

p = p->next;

}

q->next = new_node;

new_node->next = p;

}

} //此代碼原理同上只是新建一個loc

#if//在主函數(shù)中打印

printf("\n\n");

create_node(&new_node);

new_node->num = 100;

printf("please input loc:\n");

scanf("%d",&loc);

insert_node_mid_front(&head,new_node,loc);

display(head);

刪除結(jié)點

void delete_node(Link * head,int num_del)

{

Link p, q;

p = q = *head;

if(NULL == *head)

{

printf("Link is empty!\n");

return;

}

else if((*head)->num == num_del)

{

*head = (*head)->next ;

free(p);

return;

}

else

{

while(NULL != p && p->num != num_del)

{

q = p;

p = p->next;

}

if(NULL == p)

{

printf("no such node!\n");

}

else

{

q->next = p->next;

free(p);

}

}

}

**

查找結(jié)點

Link search_node(Link head,int num_serch)

{

Link p;

p = head;

if(NULL == head)

{

printf("Link is empty!\n");

return NULL;

}

else

{

while( p != NULL && p->num != num_serch)

{

p = p->next;

}

if(NULL == p)

{

return NULL;

}

else

{

return p;

}

}

}

**

對于如何使用1級指針或者2級指針參考博客

待續(xù)…

總結(jié)

以上是生活随笔為你收集整理的c语言中头结点不为零怎么写,C语言不带表头结点的单链表操作的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網(wǎng)站內(nèi)容還不錯,歡迎將生活随笔推薦給好友。