【數據結構初階】--雙向鏈表(二)

🔥個人主頁:@草莓熊Lotso

🎬作者簡介:C++研發方向學習者

📖個人專欄:?《C語言》?《數據結構與算法》《C語言刷題集》《Leetcode刷題指南》

??人生格言:生活是默默的堅持,毅力是永久的享受。???

前言:在上篇博客中我們進行了雙向鏈表概念的理解以及哨兵位頭節點的初始化,那么我們這次將會繼續來實現雙向鏈表中的其它接口,還是一樣,分布實現后再把所有的代碼展示出來?


目錄

?一.雙向鏈表的尾插

二.雙向鏈表的頭插?

三.?雙向鏈表的尾刪

四.雙向鏈表的頭刪?

五.雙向鏈表查找

六.雙向鏈表在指定位置之后插入

七.雙向鏈表指定位置刪除

八.雙向鏈表的銷毀以及初始化部分的優化

九.代碼展現

List.h:

List.c:

test.c:


?一.雙向鏈表的尾插

--實現尾插之前,我們需要先實現一個申請新節點的操作,方便后續的使用,具體操作如下:

ListNode* LTBuyNode(LTDataType x)
{ListNode* newcode = (ListNode*)malloc(sizeof(ListNode));newcode->data = x;newcode->next = newcode;newcode->prev = newcode;return newcode;
}

--利用這個我們還可以優化前面的頭節點初始化,大家可以自己先嘗試一下,接下來我們還是回到尾插的實現

List.c:

//尾插
void LTPushBack(ListNode* phead, LTDataType x)
{assert(phead);//申請一個新節點ListNode* newcode = LTBuyNode(x);//phead->prev newcode phead//先連newcodenewcode->prev = phead->prev;newcode->next = phead;//再把phead->prev的先處理掉phead->prev->next = newcode;phead->prev = newcode;
}

重點提示:?

我們先申請一個新節點,再把新節點的前驅指針和后繼指針先對應的連上,再處理受到影戲的兩個節點,因為要通過頭節點找d3,所以我們先處理phead->prev,最后再處理phead

--在測試之前,我們還需要定義一個打印的接口,便于我們觀察?

//打印
void LTPrint(ListNode* phead)
{ListNode* pcur = phead->next;while (pcur != phead){printf("%d -> ", pcur->data);pcur = pcur->next;}printf("\n");
}

--這里的pucr是從第一個節點開始的,也就是哨兵位的下一個節點,直達回到哨兵位結束,哨兵位不打印出來

test.c:

#include"List.h"void test1()
{//初始化,明天優化ListNode* plist = NULL;LTInit(&plist);//尾插LTPushBack(plist, 1);LTPushBack(plist, 2);LTPushBack(plist, 3);LTPushBack(plist, 4);LTPrint(plist);
}
int main()
{test1();return 0;
}

?--測試完成,打印沒有問題,退出碼為0


二.雙向鏈表的頭插?

?--雙向鏈表的頭插實現起來也不會很難,但注意這里的頭插可不是插入在哨兵位節點的前面哈,而是第一個節點的前面,一定不要搞錯了

List.c:

//頭插
void LTPushFront(ListNode* phead, LTDataType x)
{assert(phead);ListNode* newcode = LTBuyNode(x);//phead newcode phead->nextnewcode->prev = phead;newcode->next = phead->next;phead->next->prev = newcode;phead->next = newcode;
}

重點提示:?

這里的大體思路和尾插一樣,找到和申請的新節點有關的兩個節點,先把newcode的前驅指針和后繼指針指向對應位置,再處理需要用phead尋找的phead->next,最后再把phead需要處理的連上就可以了

test.c:?

#include"List.h"void test1()
{//初始化,明天優化ListNode* plist = NULL;LTInit(&plist);//尾插LTPushBack(plist, 1);LTPushBack(plist, 2);LTPushBack(plist, 3);LTPushBack(plist, 4);LTPrint(plist);//頭插LTPushFront(plist, 5);LTPrint(plist);
}
int main()
{test1();return 0;
}

--測試完成,打印沒有問題,頭插了一個5,退出碼為0


三.?雙向鏈表的尾刪

--實現尾刪之前,我們需要先實現一個判空的接口,如果鏈表為空則不能繼續刪除了,具體操作如下:

//判空
bool LTEmpty(ListNode* phead)
{assert(phead);return phead->next == NULL;
}

List.c:

//尾刪
void LTPopBack(ListNode* phead)
{assert(!LTEmpty(phead));ListNode* del = phead->prev;//del->prev del pheaddel->prev->next = phead;phead->prev = del->prev;free(del);del = NULL;
}

重點提示:

我們先進行一下判空,如果鏈表不為空繼續后面的操作,首先我們需要刪除的節點通過phead->prev找到,我們定義一個del,然后尾刪操作受到影響的其它兩個節點一個為del->prev,一個為head,把它們兩個需要連的連上,再釋放掉del指針就可以了

test.c:?

#include"List.h"void test1()
{//初始化,明天優化ListNode* plist = NULL;LTInit(&plist);//尾插LTPushBack(plist, 1);LTPushBack(plist, 2);LTPushBack(plist, 3);LTPushBack(plist, 4);LTPrint(plist);//頭插LTPushFront(plist, 5);LTPrint(plist);//尾刪LTPopBack(plist);LTPrint(plist);
}
int main()
{test1();return 0;
}

--測試完成,打印沒有問題,刪掉了尾部的4,退出碼為0


四.雙向鏈表的頭刪?

List.c:

//頭刪
void LTPopFront(ListNode* phead)
{assert(!LTEmpty(phead));ListNode* del = phead->next;//phead del del->nextphead->next = del->next;del->next->prev = phead;free(del);del = NULL;
}

重點提示:?

頭刪操作的思路和尾刪相似,先還是判空,然后后續需要通過del記錄下phead->next這個我們要刪除的節點,再找到兩個受到影響的節點,對應連上,最后釋放掉del就可以了

test.c:?

#include"List.h"void test1()
{//初始化,明天優化ListNode* plist = NULL;LTInit(&plist);//尾插LTPushBack(plist, 1);LTPushBack(plist, 2);LTPushBack(plist, 3);LTPushBack(plist, 4);LTPrint(plist);//頭插LTPushFront(plist, 5);LTPrint(plist);//尾刪LTPopBack(plist);LTPrint(plist);//頭刪LTPopFront(plist);LTPrint(plist);
}
int main()
{test1();return 0;
}

--測試完成,打印沒有問題,頭刪掉了5,退出碼為0


五.雙向鏈表查找

--在實現指定位置之前插入以及刪除之前,我們需要實現一個查找的接口

List.c:

//查找
ListNode* LTFind(ListNode* phead,LTDataType x)
{assert(!LTEmpty(phead));ListNode* pcur = phead->next;while (pcur != phead){if (pcur->data == x)return pcur;pcur = pcur->next;}return NULL;
}

重點提示:?

遍歷的方法和打印是一樣的,如果在遍歷過程中找到了我們需要查找的數據就返回當前位置的節點,沒有就返回空

test.c:?

#include"List.h"void test1()
{//初始化,明天優化ListNode* plist = NULL;LTInit(&plist);//尾插LTPushBack(plist, 1);LTPushBack(plist, 2);LTPushBack(plist, 3);LTPushBack(plist, 4);LTPrint(plist);//頭插LTPushFront(plist, 5);LTPrint(plist);//尾刪LTPopBack(plist);LTPrint(plist);//頭刪LTPopFront(plist);LTPrint(plist);//查找ListNode*pos=LTFind(plist, 2);if (pos)printf("找到了\n");elseprintf("沒找到\n");
}
int main()
{test1();return 0;
}

--測試完成,能夠找到,退出碼為0


六.雙向鏈表在指定位置之后插入

--我們在這里先實現一下在指定位置之后的插入操作,大家后續可以自己再嘗試一下在指定位置之前插入

List.c:

//指定位置之后插入
void LTInsert(ListNode* pos, LTDataType x)
{assert(pos);ListNode* newcode = LTBuyNode(x);//pos newcode pos->nextnewcode->prev = pos;newcode->next = pos->next;pos->next->prev = newcode;pos->next = newcode;}

重點提示:?

--在指定位置之后的插入操作其實也沒有很難,還是先斷言,后續就是先申請一個新節點,跟頭插尾插一樣,先處理newcode的前驅指針和后繼指針,然后再是受到影響的兩個節點里面先處理需要通過pos節點找到的pos->next節點,最后再處理pos

test.c:?

#include"List.h"void test1()
{//初始化,明天優化ListNode* plist = NULL;LTInit(&plist);//尾插LTPushBack(plist, 1);LTPushBack(plist, 2);LTPushBack(plist, 3);LTPushBack(plist, 4);LTPrint(plist);//頭插LTPushFront(plist, 5);LTPrint(plist);//尾刪LTPopBack(plist);LTPrint(plist);//頭刪LTPopFront(plist);LTPrint(plist);//查找ListNode* pos = LTFind(plist, 2);//指定位置之后插入LTInsert(pos, 100);LTPrint(plist);}
int main()
{test1();return 0;
}

--測試完成,打印沒有問題,在2后插入了100,退出碼為0


七.雙向鏈表指定位置刪除

List.c:

//指定位置刪除
void LTErase(ListNode* pos)
{assert(pos);//pos->prev pos pos->nextpos->prev->next = pos->next;pos->next->prev = pos->prev;free(pos);pos = NULL;
}

重點提示:?

先斷言,后續操作思路和頭刪尾刪也很像,這里是通過pos指針找到兩個受到影響的節點,我們直接處理好這兩個節點之前的關系就可以了,最后再直接釋放掉pos

test.c:?

#include"List.h"void test1()
{//初始化,明天優化ListNode* plist = NULL;LTInit(&plist);//尾插LTPushBack(plist, 1);LTPushBack(plist, 2);LTPushBack(plist, 3);LTPushBack(plist, 4);LTPrint(plist);//頭插LTPushFront(plist, 5);LTPrint(plist);//尾刪LTPopBack(plist);LTPrint(plist);//頭刪LTPopFront(plist);LTPrint(plist);//查找ListNode* pos = LTFind(plist, 2);//指定位置之后插入LTInsert(pos, 100);LTPrint(plist);//指定位置刪除LTErase(pos);LTPrint(plist);
}
int main()
{test1();return 0;
}

--測試完成,打印沒有問題,退出碼為0


八.雙向鏈表的銷毀以及初始化部分的優化

--在這里我們先來實現一下雙向鏈表的銷毀,具體的遍歷操作和之前一樣,我們在遍歷過程中每次銷毀一個節點之前先把它的下一個節點存下來,最后銷毀完后利用存下來的使它來到下一個位置,具體操作代碼如下

//銷毀
void LTDestory(ListNode* phead)
{ListNode* pcur = phead->next;while (pcur != phead){ListNode* next = pcur->next;free(pcur);pcur = next;}free(phead);phead = NULL;
}

?--大家需要注意的是我們這里其實按道理來說是要用二級指針的,但是前面其它接口都用的一級,這里和初始化部分也需要統一比較好點,我們可以在測試文件中最后銷毀完手動將頭節點置為空,那么我們的初始化操作的優化我也直接給大家展示為代碼了,其實就是改變了一下函數的返回類型,測試文件中也有所修改,在最后的代碼展現的時候大家可以看看

//頭節點初始化的優化
ListNode* LTInit()
{ListNode* phead = LTBuyNode(-1);return phead;
}

九.代碼展現

List.h:

#pragma once
#include<stdio.h>
#include<stdlib.h>
#include<assert.h>
#include<stdbool.h>typedef int LTDataType;
typedef struct ListNode
{LTDataType data;//前驅指針,指向前一個指針struct ListNode* prev;//后繼指針,指向后一個指針struct ListNode* next;
}ListNode;//初始化頭節點
void LTInit(ListNode** pphead);
//ListNode* LTInit();
//打印
void LTPrint(ListNode* phead);
//銷毀
void LTDestory(ListNode* phead);
//尾插
void LTPushBack(ListNode* phead, LTDataType x);
//頭插
void LTPushFront(ListNode* phead, LTDataType x);
//尾刪
void LTPopBack(ListNode* phead);
//頭刪
void LTPopFront(ListNode* phead);
//查找
ListNode* LTFind(ListNode* phead,LTDataType x);
//判空
bool LTEmpty(ListNode* phead);
//指定位置之后插入
void LTInsert(ListNode* pos, LTDataType x);
//指定位置刪除
void LTErase(ListNode* pos);

List.c:

#include"List.h"//頭節點初始化
void LTInit(ListNode** pphead)
{ListNode* ph = (ListNode*)malloc(sizeof(ListNode));if (ph==NULL){perror("malloc fail!");exit(1);}*pphead = ph;(*pphead)->data = -1;//隨便給個不用的就行(*pphead)->prev = *pphead;(*pphead)->next = *pphead;
}//頭節點初始化的優化
//ListNode* LTInit()
//{
//	ListNode* phead = LTBuyNode(-1);
//	phead->prev = phead;
//	phead->next = phead;
//	return phead;
//}//打印
void LTPrint(ListNode* phead)
{ListNode* pcur = phead->next;while (pcur != phead){printf("%d -> ", pcur->data);pcur = pcur->next;}printf("\n");
}//銷毀
void LTDestory(ListNode* phead)
{ListNode* pcur = phead->next;while (pcur != phead){ListNode* next = pcur->next;free(pcur);pcur = next;}free(phead);phead =NULL;
}
//判空
bool LTEmpty(ListNode* phead)
{assert(phead);return phead->next == NULL;
}ListNode* LTBuyNode(LTDataType x)
{ListNode* newcode = (ListNode*)malloc(sizeof(ListNode));newcode->data = x;newcode->next =newcode;newcode->prev =newcode;return newcode;
}
//尾插
void LTPushBack(ListNode* phead, LTDataType x)
{assert(phead);//申請一個新節點ListNode* newcode = LTBuyNode(x);//phead->prev newcode phead//先連newcodenewcode->prev = phead->prev;newcode->next = phead;//再把phead->prev的先處理掉phead->prev->next = newcode;phead->prev = newcode;
}//頭插
void LTPushFront(ListNode* phead, LTDataType x)
{assert(phead);ListNode* newcode = LTBuyNode(x);//phead newcode phead->nextnewcode->prev = phead;newcode->next = phead->next;phead->next->prev = newcode;phead->next = newcode;
}//尾刪
void LTPopBack(ListNode* phead)
{assert(!LTEmpty(phead));ListNode* del = phead->prev;//del->prev del pheaddel->prev->next = phead;phead->prev = del->prev;free(del);del = NULL;
}//頭刪
void LTPopFront(ListNode* phead)
{assert(!LTEmpty(phead));ListNode* del = phead->next;//phead del del->nextphead->next = del->next;del->next->prev = phead;free(del);del = NULL;
}//查找
ListNode* LTFind(ListNode* phead,LTDataType x)
{assert(!LTEmpty(phead));ListNode* pcur = phead->next;while (pcur != phead){if (pcur->data == x)return pcur;pcur = pcur->next;}return NULL;
}//指定位置之后插入
void LTInsert(ListNode* pos, LTDataType x)
{assert(pos);ListNode* newcode = LTBuyNode(x);//pos newcode pos->nextnewcode->prev = pos;newcode->next = pos->next;pos->next->prev = newcode;pos->next = newcode;}//指定位置刪除
void LTErase(ListNode* pos)
{assert(pos);//pos->prev pos pos->nextpos->prev->next = pos->next;pos->next->prev = pos->prev;free(pos);pos = NULL;
}

test.c:

#include"List.h"void test1()
{//初始化ListNode* plist = NULL;LTInit(&plist);////優化//ListNode* plist = LTInit();//尾插LTPushBack(plist, 1);LTPushBack(plist, 2);LTPushBack(plist, 3);LTPushBack(plist, 4);LTPrint(plist);//頭插LTPushFront(plist, 5);LTPrint(plist);//尾刪LTPopBack(plist);LTPrint(plist);//頭刪LTPopFront(plist);LTPrint(plist);//查找ListNode* pos = LTFind(plist, 2);/*if (pos)printf("找到了\n");elseprintf("沒找到\n");*///指定位置之后插入LTInsert(pos, 100);LTPrint(plist);//指定位置刪除LTErase(pos);LTPrint(plist);//銷毀LTDestory(plist);plist == NULL;
}
int main()
{test1();return 0;
}

特別補充--順序表和單鏈表的對比


往期回顧:

【數據結構初階】--單鏈表(一)

【數據結構初階】--單鏈表(二)

【數據結構初階】--雙向鏈表(一)

結語: 在這篇博客中我們實現了雙向鏈表的所有接口,大家下來也可以自己去嘗試實現以下,可以通過畫圖輔助,如果文章對你有幫助的話,歡迎評論,點贊,收藏加關注,感謝大家的支持。

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

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

相關文章

vue-cli 模式下安裝 uni-ui

目錄 easycom 自定義easycom配置的示例 npm安裝 uni-ui 準備 sass 安裝 uni-ui 注意 easycom 傳統vue組件&#xff0c;需要安裝、引用、注冊&#xff0c;三個步驟后才能使用組件。easycom將其精簡為一步。 只要組件路徑符合規范&#xff08;具體見下&#xff09;&#…

JavaSE-接口

概念在Java中&#xff0c;接口可以被看成是一種公共規范&#xff0c;是一種引用數據類型。語法1.接口的定義格式與類的定義格式基本相同&#xff0c;將class關鍵字替換為interface關鍵字&#xff1a;public interface IShape {}2.類與接口之間使用implements關鍵字來實現接口&a…

常用類學習

文章目錄字符串相關的類String的特性String對象的創建字符串相關的類String類與其他結構之間的轉換StringBuffer,StringBuilderStringBuffer類的常用方法JDK8之前日期時間APIjava.lang.System類java.util.Date類java.text.SimpleDateFormat類java.util.Calendar類JDK8中新日期時…

【Python庫包】Gurobi-Optimize (求解 MIP) 安裝

目錄Step1&#xff1a;注冊賬號Step2&#xff1a;獲取Licence另&#xff1a;完整安裝 Gurobi軟件參考本博客簡介Gurobi-Optimizer的安裝&#xff08;Python 環境&#xff09;。 Step1&#xff1a;注冊賬號 官網-Gurobi-Optimizer ??注意&#xff1a; Gurobi 是商業軟件&…

【滲透測試】NmapScanHelper 掃描輔助工具

目錄NmapScanHelper 掃描輔助工具一、功能特性二、文件說明三、使用方法1. 安裝依賴macOSUbuntu/DebianCentOS/RHEL2. 配置網段3. 運行掃描基本用法常用端口掃描示例掃描模式特殊環境模式選擇性掃描自定義文件4. 查看結果四、掃描模式說明標準模式特殊環境模式五、支持的 Nmap …

Python爬蟲入門到實戰(1)-requests庫

一.網絡爬蟲庫網絡爬蟲通俗來講就是使用代碼將HTML網頁的內容下載到本地的過程。爬取網頁主要是為了獲取網之間需要中的關鍵信息&#xff0c;例如網頁中的數據、圖片、視頻等。urllib庫:是Python自帶的標準庫&#xff0c;無須下載、安裝即可直接使用。urllib庫中包含大量的爬蟲…

深入理解設計模式之代理模式:原理、實現與應用

在軟件開發中&#xff0c;我們經常需要控制對某些對象的訪問——可能是為了延遲加載、添加額外功能或保護敏感資源。這正是代理模式大顯身手的地方。作為結構型設計模式的重要成員&#xff0c;代理模式在眾多知名框架和系統中扮演著關鍵角色。本文將全面剖析代理模式的方方面面…

VSCode - VSCode 快速跳轉標簽頁

VSCode 快速跳轉標簽頁 1、標簽頁列表快速跳轉 通過快捷鍵 Ctrl Tab 即可快速跳轉標簽頁 # 操作方式先按住 Ctrl 鍵&#xff0c;再按 Tab 鍵&#xff0c;此時&#xff0c;即可打開標簽頁列表&#xff08;保持 Ctrl 鍵一直按住&#xff09;然后&#xff0c;再按 Tab 鍵&#xf…

深入理解設計模式:享元模式(Flyweight Pattern)

在軟件開發中&#xff0c;我們經常會遇到需要創建大量相似對象的情況。如果每個對象都獨立存儲所有數據&#xff0c;將會消耗大量內存資源&#xff0c;導致系統性能下降。享元模式&#xff08;Flyweight Pattern&#xff09;正是為解決這一問題而生的經典設計模式。本文將深入探…

網絡大提速,RDMA,IB,iWrap

本章第一節介紹的存儲設備方面的創新解決了CPU訪問存儲設備的性能問題。但在實際的業務當中,數據的傳輸除了在節點內部的CPU與存儲設備間外,節點之間也存在數據傳輸的需求。本節我們就介紹在網絡傳輸方面是如何提速的。 在介紹新的網絡技術之前,我們看看傳統網絡是如何傳輸…

【C++】紅黑樹,“紅“與“黑”的較量

各位大佬好&#xff0c;我是落羽&#xff01;一個堅持不斷學習進步的大學生。 如果您覺得我的文章有所幫助&#xff0c;歡迎多多互三分享交流&#xff0c;一起學習進步&#xff01; 也歡迎關注我的blog主頁: 落羽的落羽 一、紅黑樹的概念與規則 紅黑樹是一種更加特殊的平衡二…

【愚公系列】《MIoT.VC》001-認識、安裝 MIoT.VC 軟件

??【行業認證權威頭銜】 ? 華為云天團核心成員:特約編輯/云享專家/開發者專家/產品云測專家 ? 開發者社區全滿貫:CSDN博客&商業化雙料專家/阿里云簽約作者/騰訊云內容共創官/掘金&亞馬遜&51CTO頂級博主 ? 技術生態共建先鋒:橫跨鴻蒙、云計算、AI等前沿領域…

git:tag標簽遠程管理

git tag v1&#xff1a;在當前所在分支創建標簽v1git tag -a v2 -m release version&#xff1a;創建一個帶有附注的標簽git tag -d v2&#xff1a;刪除本地標簽git tag&#xff1a;查看標簽git push origin 標簽1 標簽2……&#xff1a;把多個標簽推送到遠程git push origin -…

力扣 hot100 Day49

105. 從前序與中序遍歷序列構造二叉樹 給定兩個整數數組 preorder 和 inorder &#xff0c;其中 preorder 是二叉樹的先序遍歷&#xff0c; inorder 是同一棵樹的中序遍歷&#xff0c;請構造二叉樹并返回其根節點。 //抄的 class Solution { private:unordered_map<int, i…

jvm-sandbox-repeater 錄制和回放

https://github.com/alibaba/jvm-sandbox-repeater/blob/master/docs/user-guide-cn.md 快速錄制自己應用 step0 安裝sandbox和插件到應用服務器 curl -s https://github.com/alibaba/jvm-sandbox-repeater/releases/download/v1.0.0/install-repeater.sh | sh step1 修改repe…

【C++底層剖析】++a vs a++:到底誰是左值,誰是右值?

在 C 編程中&#xff0c;我們經常使用 a 和 a 來實現自增操作。乍一看它們只是“先加還是后加”的語法糖&#xff0c;但你真的理解它們的底層機制、返回值類型和左值右值屬性嗎&#xff1f;1. a 和 a 的基礎區別表達式名稱語義返回值類型左值 / 右值a前置自增先將 a 加 1&#…

【世紀龍科技】汽車故障診斷與排除仿真教學軟件讓課堂更高效安全

隨著汽車產業向智能化、電動化快速轉型&#xff0c;職業院校汽修專業的教學模式正面臨全新挑戰。傳統實車實訓存在成本高、風險大、場景單一等問題&#xff0c;而行業對人才的要求卻越來越高——既需要扎實的理論基礎&#xff0c;又必須具備熟練的故障診斷能力。如何在保證安全…

網絡基礎9:按流負載均衡實驗(等價路由)

實驗eNS拓撲圖&#xff1a;1. 網絡拓撲與 IP 配置AR5&#xff1a;GE0/0/0: 192.168.1.1/24&#xff08;連接 AR6&#xff09;GE0/0/1: 192.168.3.1/24&#xff08;連接 AR8&#xff09;Loopback0: 1.1.1.1/32&#xff08;源地址&#xff09;AR6&#xff1a;GE0/0/0: 192.168.1.…

4G模塊 A7680發送中文短信到手機

命令說明 基礎AT指令 ATi顯示產品的標志信息 ATCIMI查詢IMSI ATCICCID從SIM卡讀取ICCID ATCGSN查詢產品序列號 ATCPIN查詢卡狀態 ATCSQ查詢信號強度 ATCGATT查詢當前PS域狀態 ATCREG查詢GPRS注冊狀態 ATCEREG查詢4G注冊狀態 ATCGPADDR查詢PDP地址 ATCMGF選擇短信格式 ATCMGS發…

深度學習-線性神經網絡

文章目錄線性回歸基本概念隨機梯度下降矢量化加速正態分布和平方損失極大似然估計線性回歸實現從0開始**torch.no_grad()的兩種用途****為什么需要 l.sum().backward()&#xff1f;**調用現成庫softmax回歸圖像數據集從0開始實現softmax利用框架API實現課程學習自李牧老師B站的…