<em>Mac</em>Book项目 2009年学校开始实施<em>Mac</em>Book项目,所有师生配备一本<em>Mac</em>Book,并同步更新了校园无线网络。学校每周进行电脑技术更新,每月发送技术支持资料,极大改变了教学及学习方式。因此2011
2021-06-01 09:32:01
概念:連結串列是一種物理儲存結構上非連續、非順序的儲存結構,資料元素的邏輯順序是通過連結串列中的指標連結次序實現的 。
實際中連結串列的結構非常多樣,以下情況組合起來就有8種連結串列結構
單向或者雙向
帶頭或者不帶頭
迴圈或者非迴圈
雖然有這麼多的連結串列的結構,但是我們實際中最常用還是兩種結構
單向連結串列結構
#pragma once #include<stdio.h> #include<string.h> #include<stdlib.h> #include<assert.h> typedef int SLTDataType; typedef struct SListNode { int data;//資料 struct SListNode* next;//下一個節點的地址 }SListNode; void SListPrint(SListNode* phead);//列印 SListNode* BuySListNode(SLTDataType x);//搞出一個新節點 void SListPushBack(SListNode** pphead, SLTDataType x);//尾插 void SListPushFront(SListNode** pphead, SLTDataType x);//頭插 void SListPopBack(SListNode** pphead);//尾刪 void SListPopFront(SListNode** pphead);//頭刪 SListNode* SListFind(SListNode* phead, SLTDataType x);//查詢 void SListInsert(SListNode** pphead, SListNode* pos, SLTDataType x);//在pos位置之前插入 void SListInsertAfter(SListNode* pos, SLTDataType x);//在pos位置之後插入 void SListErase(SListNode** pphead, SListNode* pos);//刪除pos位置 void SListEraseAfter(SListNode* pos);//刪除pos之後位置 void SListDestroy(SListNode** pphead);//銷燬
//列印 void SListPrint(SListNode* phead) { //assert(phead);//沒必要斷言,空連結串列也能列印 SListNode* cur = phead; while (cur != NULL) { printf("%d->", cur->data); cur = cur->next; } printf("NULLn"); }
//test.c void TestSList1() { SListNode* slist;//結構體指標,用於存節點的地址 SListNode* n1 = (SListNode *)malloc(sizeof(SListNode)); SListNode* n2 = (SListNode*)malloc(sizeof(SListNode)); SListNode* n3 = (SListNode*)malloc(sizeof(SListNode)); n1->data = 1; n2->data = 2; n3->data = 3; n1->next = n2; n2->next = n3; n3->next = NULL; slist = n1; SListPrint(slist); }
//搞出一個新節點 SListNode* BuySListNode(SLTDataType x) { SListNode* newnode = (SListNode*)malloc(sizeof(SListNode)); if (newnode == NULL) { printf("malloc failn"); exit(-1); } else { newnode->data = x; newnode->next = NULL; } return newnode; }
//尾插 void SListPushBack(SListNode** pphead,SLTDataType x)//會改變實參slist,要傳二級指標 { assert(pphead);//就算連結串列是空,它的二級指標也不為空 SListNode* newnode = BuySListNode(x); if (*pphead == NULL) { *pphead = newnode; } else { //遍歷找尾 SListNode* tail = *pphead; while (tail->next != NULL) { tail = tail->next; } tail->next = newnode; } }
void TestSList2() { SListNode* slist = NULL; for (int i = 0; i < 6; i++) { SListPushBack(&slist,i); } SListPrint(slist); }
//頭插 void SListPushFront(SListNode** pphead, SLTDataType x) { assert(pphead);//就算連結串列是空,它的二級指標也不為空 SListNode* newnode = BuySListNode(x); newnode->next = *pphead; *pphead = newnode; }
void TestSList2() { SListNode* slist = NULL; for (int i = 0; i < 6; i++) { SListPushFront(&slist,i); } SListPrint(slist); }
方法1(用兩個指標,分別找最後一個和倒數第二個):
方法2(直接找倒數第二個):
//尾刪 void SListPopBack(SListNode** pphead)//如果只有一個節點但還要尾刪,就會改變實參slist,建議傳二級指標 { assert(pphead);//就算連結串列是空,它的二級指標也不為空 //三種情況: //1.空 //2.一個節點 //3.多個節點 if (*pphead == NULL) { return; } else if ((*pphead)->next == NULL)//優先順序,記得加括號 { free(*pphead); *pphead = NULL; } //第一種寫法(用兩個指標,分別找最後一個和倒數第二個) else { SListNode* prev = NULL;//找倒數第二個元素,用於將它指向NULL SListNode* tail = *pphead;//找尾 while (tail->next != NULL) { prev = tail; tail = tail->next; } free(tail); tail = NULL;//習慣性free掉就將其置空 prev->next = NULL; } //方法二(直接找倒數第二個) //else //{ //SListNode* tail = *pphead;//找尾 //while (tail->next->next != NULL) //{ // tail = tail->next; //} //free(tail->next); //tail->next = NULL; //} }
//頭刪 void SListPopFront(SListNode** pphead) { assert(pphead); //1.空 //2.非空 if (*pphead == NULL) { return; } else { SListNode* next = (*pphead)->next; free(*pphead); *pphead = next; } }
//查詢 SListNode* SListFind(SListNode* phead, SLTDataType x) { SListNode* cur = phead; while (phead != NULL) { if (cur->data == x) { return cur; } cur = cur->next; } return NULL; }
//在pos位置之前插入(一般跟find配合使用) void SListInsert(SListNode** pphead, SListNode* pos, SLTDataType x) { assert(pphead); assert(pos);//間接檢測連結串列是否為空,因為空連結串列找不到pos //1.pos是第一個節點(頭插) //2.pos不是第一個節點 if (pos == *pphead) { SListPushFront(pphead, x); } else { SListNode* prev = *pphead; while (prev->next != pos) { prev = prev->next; } SListNode* newnode = BuySListNode(x); prev->next = newnode; newnode->next = pos; } }
方法1:兩個指標,先連線pos和newnode還是先連線newnode和next都行
方法2:只有一個指標,一定要先通過pos連線newnode和下一個,再連線pos和newnode,否則會找不到下一個的地址。
//在pos位置之後插入 void SListInsertAfter(SListNode* pos, SLTDataType x) { assert(pos); SListNode* newnode = BuySListNode(x); SListNode* next = pos->next; newnode->next = next;//順序無所謂 pos->next = newnode; //或者不定義next //newnode->next = pos->next; //pos->next = newnode;//順序要定好,否則會找不到 }
//刪除pos位置 void SListErase(SListNode** pphead, SListNode* pos) { assert(pphead); assert(pos); if (pos == *pphead) { SListPopFront(pphead); } else { SListNode* prev = *pphead; while (prev->next != pos) { prev = prev->next; } prev->next = pos->next; free(pos); pos = NULL;//好習慣 } }
//刪除pos之後位置 void SListEraseAfter(SListNode* pos) { assert(pos); SListNode* next = pos->next; if (next)//防止pos是最後一個元素 { pos->next = next->next; free(next); next = NULL; } }
一個個找,一個個銷燬,最終將slist置空。
//銷燬 void SListDestroy(SListNode** pphead) { assert(pphead); SListNode* cur = *pphead; while (cur) { SListNode* next = cur->next; free(cur); cur = next; } *pphead = NULL; }
總結:單連結串列結構,適合頭插頭刪。尾部或者中間某個位置插入刪除不適合。如果要使用連結串列單獨儲存資料,那我們之後會學的雙向連結串列更合適。單連結串列學習的意義:
連結串列系列有很多重點內容,我會花不少時間來跟大家講解連結串列,相信大家跟著練習的話程式設計嚴謹性會大大提升,加油哦!
到此這篇關於C語言資料結構超詳細講解單向連結串列的文章就介紹到這了,更多相關C語言 單向連結串列內容請搜尋it145.com以前的文章或繼續瀏覽下面的相關文章希望大家以後多多支援it145.com!
相關文章
<em>Mac</em>Book项目 2009年学校开始实施<em>Mac</em>Book项目,所有师生配备一本<em>Mac</em>Book,并同步更新了校园无线网络。学校每周进行电脑技术更新,每月发送技术支持资料,极大改变了教学及学习方式。因此2011
2021-06-01 09:32:01
综合看Anker超能充系列的性价比很高,并且与不仅和iPhone12/苹果<em>Mac</em>Book很配,而且适合多设备充电需求的日常使用或差旅场景,不管是安卓还是Switch同样也能用得上它,希望这次分享能给准备购入充电器的小伙伴们有所
2021-06-01 09:31:42
除了L4WUDU与吴亦凡已经多次共事,成为了明面上的厂牌成员,吴亦凡还曾带领20XXCLUB全队参加2020年的一场音乐节,这也是20XXCLUB首次全员合照,王嗣尧Turbo、陈彦希Regi、<em>Mac</em> Ova Seas、林渝植等人全部出场。然而让
2021-06-01 09:31:34
目前应用IPFS的机构:1 谷歌<em>浏览器</em>支持IPFS分布式协议 2 万维网 (历史档案博物馆)数据库 3 火狐<em>浏览器</em>支持 IPFS分布式协议 4 EOS 等数字货币数据存储 5 美国国会图书馆,历史资料永久保存在 IPFS 6 加
2021-06-01 09:31:24
开拓者的车机是兼容苹果和<em>安卓</em>,虽然我不怎么用,但确实兼顾了我家人的很多需求:副驾的门板还配有解锁开关,有的时候老婆开车,下车的时候偶尔会忘记解锁,我在副驾驶可以自己开门:第二排设计很好,不仅配置了一个很大的
2021-06-01 09:30:48
不仅是<em>安卓</em>手机,苹果手机的降价力度也是前所未有了,iPhone12也“跳水价”了,发布价是6799元,如今已经跌至5308元,降价幅度超过1400元,最新定价确认了。iPhone12是苹果首款5G手机,同时也是全球首款5nm芯片的智能机,它
2021-06-01 09:30:45