單鏈表相關操作(插入,刪除,查找)

通過上一節我們知道順序表的優點:

可隨機存儲(O(1)):查找速度快

存儲密度高:每個結點只存放數據元素,而單鏈表除了存放數據元素之外,還需存儲指向下一個節點的指針

http://t.csdn.cn/p7OQf

但是順序表也有明顯的缺點,就是需要大片的連續空間,改變容量不方便,所以出現了單鏈表

目錄

一.初始化單鏈表

二.插入結點

1.帶頭結點的插入

2.不帶頭結點的插入:不存在第’0‘個結點,因此i=1時,需要特殊處理

補充:帶頭結點

指針結點的后插操作

指針的前插操作

三.刪除結點

1.帶頭節點的刪除

2.不帶頭節點的刪除

3.刪除指定節點

四.單鏈表的查找

1.按位查找:查找第i個節點的值

2.按值查找:查找鏈表中是否有元素e

補充:求表的長度


一.初始化單鏈表

typedef struct LNode{ElemType data;    //每個節點存放一個數據元素struct LNode *next;//指針指向下一個節點
}LNode,*LinkList;
//這里的LinkList==》typedef struct LNode *LinkList,定義一個指向結構體的指針
//在這里
//LNode *L與LinkList L;//都是表示指向單鏈表第一個節點的指針
//LNode *L強調的是一個節點
//LinkList L強調的是一個單鏈表/*不帶頭節點的單鏈表
bool InitList(LinkList &L)
{L=NULL;//防止空間中存在臟數據return true;}bool Empty(LinkList L)
{return (L=NULL);
}void test()
{LinkList L;InitList(L);}
*///帶頭結點的單鏈表
LinkList InitList(LinkList &L)
{L=(LNode *)malloc(sizeof(LNode));//分配一個頭結點if(L==NULL)return NULL;L->next=NULL;//聲明一個指向單鏈表的指針return L;}bool Empty(LinkList L)
{if(L->next==NULL){return true;}    elsereturn false;}
//我們可以把頭結點看作第0個結點,這樣寫代碼更加方便

二.插入結點

1.帶頭結點的插入

bool ListInsert(LinkList &L,int i,ElemType e)//i表示插入的位置,e表示插入的元素
{if(i<1){return false;}LNode *p;//指針p指向當前掃描到的結點int j=0;//當前p指向的是第幾個結點p=L;    //指向頭節點,頭節點是第0個節點while(p!=NULL && j<i-1)//循環找到第i-1個結點{p=p->next;j++;}if(p==NULL){return false;}LNode *s=(LNode *)malloc(sizeof(LNode));s->data=e;s->next=p->next;p->next=s;return true;}

若先p->next=s,再s->next=p->next,即

?帶頭結點的插入

最好情況:插在表頭O(1)

最壞情況:插在表尾O(n)

平均情況:O(n)

2.不帶頭結點的插入:不存在第’0‘個結點,因此i=1時,需要特殊處理

bool ListInsert(LinkList &L,int i,ElemType e)
{if(i<1)return false;if(i==1)//插入第1個結點的操作與其他節點操作不同    {LNode *s=(LNode *)malloc(sizeof(LNode));s->data=e;s->next=L;L=s;//頭指針指向新結點return true;}LNoden *p;int j=1;//除了這里j=1和帶頭結點的指針不同,其他是相同的p=L;while(p!=NULL && j<i-1){p=p->next;j++;}if(p==NULL){return false;}LNode *s=(LNode *)malloc(sizeof(LNode));s->data=e;s->next=p->next;p->next=s;return true;
}

刪除第一個元素時,需要更改頭指針L?

補充:帶頭結點

指針結點的后插操作

//在p結點之后,插入元素e
bool InsertNextNode(LNode *p,ElemType e)
{if(p==NULL)return false;LNode *s=(LNode *)malloc(sizeof(LNode));if(s=NULL)//如果內存分配失敗,如內存不足等return false;s->data=e;s->next=p->next;    p->next=s;return true;}

?指針的前插操作

1.第一種方法:通過前驅節點完成前插操作

需要傳入頭節點才能找到p的前驅結點,即

bool InsertPriorNode(LinkList L,LNode *p,ElemType e)

bool InsertPriorNode(LinkList L,LNode *p,ElemType e)
{if(p==NULL)return false;LNode *s=(LNode*)malloc(sizeof(LNode));if(s==NULL)return false;LNode *current=L;while(current->next!=p)current=current->next;s->data=e;s->next=current->next;current->next=s;return true;
}

?在這里時間復雜度為O(n),如何減小時間復雜度,可以用第二種方法

2.第二種方法:通過結點的數據交換完成前插操作

bool InsertPriorNode(LNode *p,ElemType e)
{if(p==NULL)return false;LNode *s=(LNode *)malloc(sizeof(LNode));if(s==NULL)return false;s->next=p->next;p->next=s;    //新節點s連到p之后s->data=p->data;//將p中元素復制到s中p->data=e;//p中元素覆蓋為ereturn true;}

?關鍵在于s->data=p->data;p->data=e;這樣實現了兩節點的數據交換,實現了在p結點前插入e元素,同時這里的時間復雜度是O(1)

所以對于插入節點可以觀察到如下兩個規律

1.先后再前

s->next=p->next;

p->next=s;

2.先小后大

在第一個節點插入

s->next=L;

L=s????????//頭指針指向新插入的節點s?

三.刪除結點

1.帶頭節點的刪除

bool ListDelete(LinkList &L,int i,ElemType &e)
{if(i<1){return false;}LNode *p=L;int j=0;while(p!=NULL && j<i-1)//這里是尋找要刪除結點的前驅結點{p=p->next;j++;}    if(p==NULL)return false;if(p->next==NULL)//如果要刪除結點的前驅結點為NULL,那么刪除就無意義了return false;LNode *q=p->next;//令q指向被刪除結點e=q->data;//用e返回元素的值p->next=q->next;//將*q結點從鏈表中斷開free(q);//釋放qreturn true;
}

最好時間復雜度為O(1):刪除第一個節點

最壞和平均時間復雜度為O(n)

2.不帶頭節點的刪除

bool ListDelete(LinkList& L, int i, ElemType& e) {if (i < 1)return false;if (i == 1) {    LNode* p = L;L = L->next;free(p);return true;}LNode* p = L;int j = 1;while (p != NULL && j < i - 1) {//尋找刪除節點的前驅節點p = p->next;j++;}if (p == NULL || p->next == NULL)return false;LNode* q = p->next;e = q->data;p->next = q->next;free(q);return true;
}

?3.刪除指定節點

//刪除指定節點p
bool DeleteNode(LNode *p)
{if(p==NULL)return false;LNode *q=p->next;    //    令q指向*p的后繼節點q->data=p->next->data;p->next=q->next;//將*q節點從鏈中斷開free(q);//釋放后繼節點的存儲空間return true;}
//如果p的后繼節點剛好為NULL,那么p->next->data指向空所以這段代碼對此情況不適用
//針對此情況還是要找到其前驅節點,然后進行刪除

找前驅節點進行刪除

bool DeleteNode(LinkList L, LNode* p, ElemType& e) {if (p == NULL)return false;LNode* q = L;while (q->next != p)q = q->next;q->next = NULL;e = p->data;free(p);return true;
}

四.單鏈表的查找

1.按位查找:查找第i個節點的值

LNode *GetElem(LinkList L,int i)
{if(i<0)return false;LNode *p=L;int j=0;while(p!=NULL && j<i)//循環找到第i個節點{p=p->next;j++;}return p;}

平均時間復雜度O(n)

2.按值查找:查找鏈表中是否有元素e

LNode *LocateElem(LinkList L,ElemType e)
{LNode *p=L->next;//從第一個節點開始查找數據域為e的節點while(p!=NULL && p->data!=e)p=p->next;return p;//找到后返回該節點的指針,否則為NULL
}

平均時間復雜度O(n)

補充:求表的長度

int length(LinkList L)
{int len=0;LNode *p=L;while(p!=NULL){p=p->next;len++;}return len;}

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

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

相關文章

【2023年11月第四版教材】《第4章-信息系統管理(合集篇)》

第4章-信息系統管理之管理方法&#xff08;第四版新增章節&#xff09;&#xff08;第一部分&#xff09; 章節說明1 管理方法1.1 信息系統四個要素1.2 信息系統四大領域1.3 信息系統戰略三角1.4 信息系統架構轉換1.5 信息系統體系架構1.6 信息系統運行1.7 運行和監控1.8 管理和…

北郵鄧中亮:深度融合5G+北斗,實現高精準定位

如今&#xff0c;萬物互聯時代&#xff0c;物與物、物與人、人與人之間需要實現更多的互聯。在如此復雜多變的環境中&#xff0c;定位技術面臨著著更多挑戰和需求&#xff0c;需要不斷的創新和改進。唯有如此&#xff0c;才能滿足未來智能交通、無人駕駛和工業互聯網等領域的高…

kafka基本概念及操作

kafka介紹 Kafka是最初由Linkedin公司開發&#xff0c;是一個分布式、支持分區的&#xff08;partition&#xff09;、多副本的 &#xff08;replica&#xff09;&#xff0c;基于zookeeper協調的分布式消息系統&#xff0c;它的最大的特性就是可以實時的處理大量數據以滿足各…

【LeetCode】242 . 有效的字母異位詞

242 . 有效的字母異位詞&#xff08;簡單&#xff09; 方法&#xff1a;哈希表 思路 首先判斷兩個字符串長度是否相等&#xff0c;不相等直接返回 false&#xff1b;接下來設置一個長度為26 的哈希表&#xff0c;分別對應26個小寫字母&#xff1b;遍歷兩個字符串&#xff0c;…

Go語言工程實踐之測試與Gin項目實踐

Go 語言并發編程 及 進階與依賴管理_軟工菜雞的博客-CSDN博客 03 測試 回歸測試一般是QA(質量保證)同學手動通過終端回歸一些固定的主流程場景 集成測試是對系統功能維度做測試驗證,通過服務暴露的某個接口,進行自動化測試 而單元測試開發階段&#xff0c;開發者對單獨的函數…

day-21 代碼隨想錄算法訓練營(19)二叉樹part07

530.二叉搜索樹的最小絕對差 思路一&#xff1a;二叉搜索樹的中序遍歷必為升序數組&#xff0c;加入數組后計算相鄰兩個數差值&#xff0c;即可求出最小絕對差 思路二&#xff1a;同樣的思路&#xff0c;中序遍歷&#xff0c;直接使用指針記錄上一個節點&#xff0c;同時更新…

KAFKA第二課之生產者(面試重點)

生產者學習 1.1 生產者消息發送流程 在消息發送的過程中&#xff0c;涉及到了兩個線程——main線程和Sender線程。在main線程中創建了一個雙端隊列RecordAccumulator。main線程將消息發送給RecordAccumulator&#xff0c;Sender線程不斷從RecordAccumulator中拉取消息發送到K…

03-基礎入門-搭建安全拓展

基礎入門-搭建安全拓展 1、涉及的知識點2、常見的問題3、web權限的設置4、演示案例-環境搭建&#xff08;1&#xff09;PHPinfo&#xff08;2&#xff09;wordpress&#xff08;3&#xff09;win7虛擬機上使用iis搭建網站&#xff08;4&#xff09;Windows Server 2003配置WEB站…

C#應用處理傳入參數 - 開源研究系列文章

今天介紹關于C#的程序傳入參數的處理例子。 程序的傳入參數應用比較普遍&#xff0c;特別是一個隨操作系統啟動的程序&#xff0c;需要設置程序啟動的時候不顯示主窗體&#xff0c;而是在后臺運行&#xff0c;于是就有了傳入參數問題&#xff0c;比如傳入/h或者/min等等。所以此…

YOLO v8目標跟蹤詳細解讀(二)

上一篇&#xff0c;結合代碼&#xff0c;我們詳細的介紹了YOLOV8目標跟蹤的Pipeline。大家應該對跟蹤的流程有了大致的了解&#xff0c;下面我們將對跟蹤中出現的卡爾曼濾波進行解讀。 1.卡爾曼濾波器介紹 卡爾曼濾波&#xff08;kalman Filtering&#xff09;是一種利用線性…

歐拉OS 使用 CentOS 7 yum repo

一、下載CentOS的repo的yum文件 任何基于CentOS的yum的repo 的url是這樣的&#xff1a; 但歐拉OS輸出這個變量為&#xff1a;openEuler 20.03 (LTS-SP3) 那明顯歐拉想要使用這個yum的url找不到這個版本&#xff0c; 所以直接講這個變量替換為 7, Centos 7的7 然后執行&…

wget 詳解

wget 詳解 wget 詳解基本用法&#xff1a;命令參數&#xff1a;遞歸下載&#xff1a;斷點續傳&#xff1a;限速下載&#xff1a;后臺下載&#xff1a; 示例 wget 詳解 wget&#xff08;Web Get&#xff09;是一個用于從網絡上下載文件的命令行工具&#xff0c;常用于在 Linux …

從零實戰SLAM-第七課(多視角幾何)

在七月算法報的班&#xff0c;老師講的蠻好。好記性不如爛筆頭&#xff0c;關鍵內容還是記錄一下吧&#xff0c;課程入口&#xff0c;感興趣的同學可以學習一下。 --------------------------------------------------------------------------------------------------------…

整型int溢出引起的crash

線上系統發生了crash&#xff0c;后發現是整型溢出。 1、初始化函數的偽代碼&#xff1a; init_mem(int count, int size){for(int i0; i<count; i)mem_list[i] i*size; # 溢出發生的地方} 2、問題分析&#xff1a; 原有的變量 i、size 為有符號的int類型&#xff0c;i…

設計模式--策略模式

目錄 一.場景 1.1場景 2.2 何時使用 2.3個人理解 二. 業務場景練習 2.1業務: 2.2具體實現 2.3思路 三.總結 3.1策略模式的特點&#xff1a; 3.2策略模式優點 3.3策略模式缺點 一.場景 1.1場景 許多相關的類僅僅是行為有異&#xff0c;也就是說業務代碼需要根據場景不…

Android數字價格變化的動畫效果的簡單實現

原理&#xff1a;使用ValueAnimator屬性動畫類實現&#xff0c;它通過值的改變手動設置對象的屬性值來實現動畫效果。直接貼代碼&#xff1a; public static void doNumberAnim(TextView tvPrice, float startNumber, float endNumber) {ValueAnimator animator ValueAnimato…

C語言中的 RSA加密和解密算法: 深度探索與實現

C語言中的 RSA加密和解密算法: 深度探索與實現 RSA加密算法是一種非對稱加密算法&#xff0c;即公開密鑰加密&#xff0c;私有密鑰解密。在公開密鑰加密和私有密鑰解密的過程中&#xff0c;密鑰是不同的&#xff0c;這是與其他加密算法的主要區別。RSA算法的安全性依賴于大數分…

ssm+mybatis無法給帶有下劃線屬性賦值問題

原因&#xff1a;mybaitis根據配置&#xff0c;將有下劃線的字段名改為了駝峰格式。 具體見&#xff1a;ssmmybatis無法給帶有下劃線屬性賦值問題&#xff0c;無法獲取數據庫帶下劃線的字段值 - 開發者博客 解決方式&#xff1a; 直接將實體類中的下劃線去掉返回值使用resul…

歸并排序 與 計數排序

目錄 1.歸并排序 1.1 遞歸實現歸并排序&#xff1a; 1.2 非遞歸實現歸并排序 1.3 歸并排序的特性總結: 1.4 外部排序 2.計數排序 2.1 操作步驟: 2.2 計數排序的特性總結: 3. 7種常見比較排序比較 1.歸并排序 基本思想: 歸并排序(MERGE-SORT)是建立在歸并操作上的一種…

代理技術在網絡安全、爬蟲和數據隱私中的多重應用

1. Socks5代理&#xff1a;靈活的數據中轉 Socks5代理協議在網絡通信中起著關鍵作用。與其他代理技術不同&#xff0c;Socks5代理不僅支持TCP連接&#xff0c;還能夠處理UDP流量&#xff0c;使其在需要實時數據傳輸的場景中表現尤為出色。通過將請求和響應中轉到代理服務器&am…