單鏈表的學習與基礎運用p

當我們在實際做項目,或者是自主開發一點小東西的時候,往往會儲存一些數據,有時候我們需要添加這些數據,有時候需要刪除,而有時候,僅僅只需要查找到就行。鏈表中的每一個節點都是一個獨立開辟的空間,就像一個個的小箱子。那我們要如何將這些箱子串聯起來呢?這時候,鏈表就發揮了作用。一個最基本的節點,應當如下圖組成

typedef char x;
typedef struct SlistNote SlistNote;struct SlistNote
{x data;SlistNote* next;
};

因為我們可能需要不斷的改變數據的類型,所以在最初我們利用typedef來進行重定義。并且因為結構體指針每次創建名都太長,索性直接將名字進行替換

而上圖最重要的,其實是結構體中的內容:1.數據。在這個節點中存放著相應的數據? 2.指向下一個節點的地址。如上圖的next,便是指向下一個節點的地址。

因此,當我們想使用一個鏈表的時候,我們其實只要找到第一個節點的地址就可以了。

那么,我們要如何實現鏈表的初始化,前插后插,前刪后刪,查詢,定點操作呢?讓我們一個一個來。

初始化

SListNote* SltBuyNote(SLT_type x)
{SListNote* newnote = (SListNote*)malloc(sizeof(SListNote));assert(newnote);newnote->data = x;newnote->next = NULL;return newnote;
}

我們想要實現尾插和頭插,需要先把要插入的節點準備好。以上代碼,便是數據的初始化過程。先開辟出一片空間,并將這個空間的地址賦值給newnote這個指針。接著進行assert,避免前面的開辟空間失敗進而導致后續的一系列錯誤。接著將數據進行賦值,暫時先把next指針定義為空指針,防止變成野指針,接著將剛剛創建的這個指針給return了。

尾插

void BackInsert(SListNote** pphead, SLT_type x)
{SListNote* newnote = SltBuyNote(x);if (*pphead == NULL){*pphead = newnote;}else{SListNote* ppend = *pphead;while (ppend->next){ppend = ppend->next;}ppend->next = newnote;}
}

當我們知道如何初始化節點以后,我們便可以開始一些基本的操作,比如尾插。在最開始,我們先創建出一個節點newnote,這個節點內部的數據就是我們要插入的數據。接著,我們判斷一下被插入的節點的是否為空,若為空,則直接將newnote設置為初始節點,若不為空,那便先通過while循環找到ppend,也就是該結構體的末端。接著讓結構體末端的next指針指向newnote,那便完成了尾插。

頭插

void FrontInsert(SListNote** pphead, SLT_type x)
{SListNote* newnote = SltBuyNote(x);if (*pphead == NULL){*pphead = newnote;}else{newnote->next = *pphead;*pphead = newnote;}
}

頭插相比較于尾插要更簡單一些,前面基本相似,在else這邊,我們只需要把新節點的next指針指向*pphead,那其實就已經插上了。但是這樣有一些錯誤,因為此時鏈表的頭部已經發生改變,變成了newnote,因此,我們需要手動把節點地址改為newnote地址。

頭刪

void FrontDel(SListNote** pphead)
{assert(pphead && *pphead);SListNote* pcur = *pphead;if (pcur->next == NULL){free(*pphead);*pphead = NULL;}SListNote* pcur = *pphead;*pphead = pcur->next;free(pcur);
}

頭刪也是比較簡單的,在頭刪函數中,我們首先需要先判斷到底有沒有數據,利用assert函數完成,如果有,再判斷有幾個數據,如果只有一個,那便是將頭地址給刪除,如果多于一個,那就將原先的頭地址賦給一個值做備份,接著將頭地址改變為下一個節點地址,再釋放掉之前的頭地址,即可完成頭刪。

尾刪

void BackDel(SListNote** pphead)
{assert(pphead && *pphead);SListNote* pcur = *pphead;if (pcur->next == NULL){free(*pphead);*pphead = NULL;}else{while (pcur->next->next){pcur = pcur->next;}free(pcur->next);pcur->next->next = NULL;pcur->next = NULL;}

尾刪前面幾部類似于頭刪,如果已經確定有大于1個的數據,那就利用while精確定位到最后一個數據處,接著釋放掉最后一個數據的地址并賦NULL值。

指定位置刪除

void PosDel(SListNote** pphead, int pos)
{int count = 0;SListNote* pcur = *pphead;assert(pphead && *pphead);if (pos == 0){FrontDel(pphead);}else{while (pcur){pcur = pcur->next;count++;}pcur = *pphead;count = 0;while (count < pos - 1){pcur = pcur->next;count++;}SListNote* ppos = pcur->next;pcur->next = pcur->next->next;free(ppos);ppos = NULL;}
}

我們先斷言待刪鏈表不是空鏈表,接著看待刪位置是不是首節點,如果是首節點,那么直接執行頭刪,如果不是,則接著進行下一步。通過while循環找到pos位置處的節點,接著將這個節點的上一個節點的next指針連接到pos位置的下一個節點,接著刪除pos位置處的節點,將其free掉。

指定位置插入

指定位置插入分為前插和后插,不同的插入方式需要不同的代碼來實現

前插:

void FrontPosInsert(SListNote** pphead, int pos, SLT_type x)
{SListNote* newnote = SltBuyNote(x);if (*pphead == NULL){*pphead = newnote;}else{if (pos == 0){FrontInsert(pphead, x);}else{SListNote* pcur = *pphead;int count = 0;while (count != pos-1){pcur = pcur->next;count++;if (pcur == NULL){printf("不在可執行范圍內!");return 0;}}SListNote* ppos = pcur->next;pcur->next = newnote;newnote->next = ppos;}}
}

先創建一個節點newnote,接著判斷鏈條是否為空鏈條,若是空鏈條,則將*pphead直接賦一個newnote,若不是,則開始判斷pos的數值,若pos為0的話,那么就執行前插函數,若pos不為0,則在進行下一步。先找到pos所代表的節點的前一個節點,接著繼續判斷,若該節點已經超過已有的節點,則進行提醒并直接返回,當然,你也可以選擇進行一次后插。若該pos符合以上規則,則開始進行插入。

后插

void BackPosInsert(SListNote** pphead, int pos, SLT_type x)
{SListNote* newnote = SltBuyNote(x);if (*pphead == NULL){*pphead = newnote;}else{SListNote* pcur = *pphead;int count = 0;while (count != pos){pcur = pcur->next;count++;if (pcur == NULL){printf("不在可執行范圍內!");return 0;}}SListNote* ppos = pcur->next;pcur->next = newnote;newnote->next = ppos;}
}

尾插與頭插大體相似,在一些細節處略微改動,例如在后續找pos位置時,我們找到的是pos的位置,而之前是找到pos前面一個節點,這方面略有不同。其他大體相同。

查找節點

void Finding(SListNote** pphead, SLT_type x)
{assert(pphead && *pphead);SListNote* pcur = *pphead;int count = 0;while (pcur){if (pcur->data == x){printf("找到了!在%d處\n", count);return;}count++;pcur = pcur->next;}printf("沒找到");
}

查找節點并不難,用到的方法和之前許多代碼相似,可大致看看上圖。

摧毀鏈表

void Sli_destory(SListNote** pphead)
{assert(pphead && *pphead);SListNote* pcur = *pphead;while (pcur){SListNote* next = pcur->next;free(pcur);pcur = next;}*pphead = NULL;

首先我們也還是先斷言一下節點地址的存在性,接著從頭到尾一個節點一個節點的去刪除,為了方便顯示,我在最后又讓首節點顯示了個NULL,已證明已經刪除完成。

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/web/41328.shtml
繁體地址,請注明出處:http://hk.pswp.cn/web/41328.shtml
英文地址,請注明出處:http://en.pswp.cn/web/41328.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

聚類分析方法(一)

目錄 一、聚類分析原理&#xff08;一&#xff09;聚類分析概述&#xff08;二&#xff09;聚類的數學定義&#xff08;三&#xff09;簇的常見類型&#xff08;四&#xff09;聚類框架及性能要求&#xff08;五&#xff09;簇的距離 二、劃分聚類算法&#xff08;一&#xff0…

Java 有什么必看的書?

Java必看經典書有這兩本&#xff1a; 1、Java核心技術速學版&#xff08;第3版&#xff09; 經典Java開發基礎書CoreJava速學版本&#xff01;Java入門優選書籍&#xff0c;更新至Java17&#xff0c;內容皆是精華&#xff0c;讓Java學習更簡單&#xff0c;讓Java知識應用更快速…

【Linux】什么是進程間通信?方式有哪些?本質理解?

&#x1f490; &#x1f338; &#x1f337; &#x1f340; &#x1f339; &#x1f33b; &#x1f33a; &#x1f341; &#x1f343; &#x1f342; &#x1f33f; &#x1f344;&#x1f35d; &#x1f35b; &#x1f364; &#x1f4c3;個人主頁 &#xff1a;阿然成長日記 …

使用 ChronicleMap 擴展高性能內存緩存

1.擴展內存緩存的挑戰 我們用于與各種程序化和需求方平臺 (DSP) 集成的應用程序之一是低延遲、高吞吐量的基于 JVM 的應用程序。這是 付款憑單&#xff08;DV&#xff09;付前前驗證解決方案的核心組件。自多年前成功推出此解決方案以來&#xff0c;我們不斷添加多項關鍵功能&…

【ChatGPT】全面解析 ChatGPT:從起源到未來

ChatGPT 是由 OpenAI 開發的一個基于 GPT&#xff08;Generative Pre-training Transformer&#xff09;架構的聊天機器人。通過自然語言處理&#xff08;NLP&#xff09;技術&#xff0c;ChatGPT 能夠理解和生成語言&#xff0c;與人類進行對話。本文將深入探討其起源、發展、…

SpringSecurity源碼分析-過濾器鏈是如何植入到spring中的

SpringSecurity源碼分析-過濾器鏈是如何植入到spring中的 一切的源頭都是因為在web.xml中配置了這樣一個Filter <!--security--><filter><filter-name>springSecurityFilterChain</filter-name><filter-class>org.springframework.web.filter.…

NoSQL 之 Redis 集群部署

前言&#xff1a; &#xff08;1&#xff09;主從復制&#xff1a;主從復制是高可用Redis的基礎&#xff0c;哨兵和集群都是在主從復制基礎上實現高可用 的。主從復制主要實現了數據的多機備份&#xff0c;以及對于讀操作的負載均衡和簡單的故障恢復。缺陷&#xff1a; 故障…

vue3+antd 實現文件夾目錄右鍵菜單功能

原本的目錄結構&#xff1a; 右鍵菜單&#xff1a; 點擊菜單以后會觸發回調&#xff1a; 完整的前端代碼&#xff1a; <template><a-directory-treev-model:expandedKeys"expandedKeys"v-model:selectedKeys"selectedKeys"multipleshow-li…

在 Docker 容器中運行 Vite 開發環境,有這兩個問題要注意

容器化開發給我們帶來了很多便捷&#xff0c;但是在開發環境下也有一些問題要注意&#xff0c;如果不解決這些問題&#xff0c;你的開發體驗不會很好。 容器啟動正常&#xff0c;卻無法訪問 我們用 Docker 啟動一個 Vite Vue3 項目的開發環境后&#xff0c;發現端口日志一切…

計算機如何存儲浮點數

浮點數組成 在計算機中浮點數通常由三部分組成&#xff1a;符號位、指數位、尾數位。IEEE-754中32位浮點數如下&#xff1a; 上圖32bit浮點數包含1bit的符號位&#xff0c;8比特的指數位和23bit的尾數位。對于一個常規浮點數&#xff0c;我們來看看它是如何存儲和計算的。這里…

conda env pip install error:No space left on device

conda 環境 pip install error&#xff1a;No space left on device 文章目錄 conda 環境 pip install error&#xff1a;No space left on device現象1 實驗2 分析和解決辦法 現象 非root用戶的服務器&#xff0c;需要安裝環境&#xff0c;安裝的環境超過2GB sudo pip insta…

醫療機器人中的具身智能進展——自主超聲策略模型的任務編碼和局部探索

醫療機器人一直是具身智能的研究熱點。醫學圖像、醫療觸診、血壓血氧、心率脈搏和生物電信號等多模態生物醫學信息&#xff0c;不斷豐富著醫療機器人的感知范疇。 自主超聲 “自主超聲”屬于具身智能醫療機器人領域中話題度較高的研究方向。作為臨床檢查的重要手段之一&#…

線性系統理論及應用GUI設計及仿真

目錄 1.控制系統的狀態空間模型 1.1.狀態空間模型 1.2 傳遞函數模型 1.3 傳遞函數轉換為狀態空間模型 1.4.狀態空間模型轉換為傳遞函數 1.5.狀態空間模型轉化為約當標準型 2.線性系統的時域分析 2.1.矩陣指數函數的計算 2.2.線型定常連續系統的狀態空間模型求解 3.線…

ubuntu24.04按關鍵字卸載不需要的apt包

使用的時候發現一個imagemagic無法正常讀取文件&#xff0c;試圖卸載 man apt經過嘗試后&#xff0c;發現list的一個神奇關鍵字&#xff0c;用來顯示已安裝的軟件包 sudo apt list --installed | grep image按image關鍵字過濾&#xff1a; 之后按軟件名卸載即可 sudo apt pu…

開關電源——調制模式和工作模式

一、開關電源的調制模式 開關電源作為一種廣泛應用于電子設備中&#xff0c;用于將一定電壓和電流轉換為另一種電壓和電流的技術&#xff0c;以下是開關電源三種常見的調制模式&#xff1a; 脈沖寬度調制&#xff08;Pulse Width Modulation&#xff09; 脈沖頻率調制&#xff…

上升與下降

目錄 開頭程序程序的流程圖關于上升與下降的動畫(程序的效果)結尾 開頭 大家好&#xff0c;我叫這是我58。今天&#xff0c;我們要來看一個關于上升與下降的動畫和這個動畫相關的內容。 程序 #define _CRT_SECURE_NO_WARNINGS 1 #define HIGH 10 #include <stdio.h> #…

高德地圖 key 和安全密鑰使用

參考高德地圖&#xff1a;JS API 安全密鑰使用 高德地圖 key 和安全密鑰使用 一、通過明文方式設置參數查看如下成功后返回的信息 二、通過代理服務器轉發實驗&#xff1a;通過本地地址轉發返回錯的錯誤信息&#xff0c;如下通過正確的項目的的服務地址&#xff0c;返回正常參數…

【VUE基礎】VUE3第一節—vite創建vue3工程

什么是VUE Vue (發音為 /vju?/&#xff0c;類似 view) 是一款用于構建用戶界面的 JavaScript 框架。它基于標準 HTML、CSS 和 JavaScript 構建&#xff0c;并提供了一套聲明式的、組件化的編程模型&#xff0c;幫助你高效地開發用戶界面。無論是簡單還是復雜的界面&#xff0…

Java+MySQL8.0.36+ElementUI數字化產科信息管理系統之”五色管理”

JavaMySQL8.0.36ElementUI數字化產科信息管理系統之”五色管理” 一、數字化產科信息管理系統概述 數字化產科信息管理五色管理是一種基于孕產婦妊娠風險的分類管理方法&#xff0c;通過數字化手段實現孕產婦全周期的健康風險評估與管理。該方法將孕產婦按照風險等級分為綠色、…

DC-DC充放電原理

文章目錄 前言1. 電子器件1.1 電容1.2 電感 2. 升壓電路3. 降壓電路4. 電壓均衡電路4.1 被動均衡4.2 主動均衡 5. 我的疑問5.1 對于升壓電路&#xff0c;怎么設計升壓到多少V后&#xff0c;停止升壓&#xff1f;5.2 什么是等效電阻&#xff1f;5.3 快充是如何實現的&#xff1f…