數據結構和算法-單鏈表

數據結構和算法-單鏈表

1. 鏈表介紹

??鏈表是有序的列表,但是它在內存中是存儲如下

在這里插入圖片描述

圖1 單鏈表示意圖

小結:

  1. 鏈表是以節點的方式存儲
  2. 每個節點包含data域,next域,指向下一個節點。
  3. 如圖:發現鏈表的各個節點不一定是連續存儲。比如地址為150的節點下一個節點的地址不為160,而是指向地址為110的節點。
  4. 鏈表分帶頭節點的鏈表沒有頭節點的鏈表,根據實際的需求來確定。

單鏈表(帶頭結點)邏輯結構示意圖如下

在這里插入圖片描述

圖2 帶頭結點的單鏈表

注意:圖2中邏輯結構的連接并不是按照地址的順序畫的,而是按照每個節點的next域的內存地址連接的。真實的內存存儲世圖1所示

2. 單鏈表的應用實例

使用帶head頭的單向鏈表實現-水滸英雄排行榜管理

  1. 完成對英雄人物的增刪改查操作,注:刪除和修改,查找。
  2. 第一種方法在添加英雄時,直接添加到鏈表尾部
  3. 第二種方法在添加英雄時,根據排名將英雄插入到指定位置(如果有這個排名,則添加失敗,并給出提示)

思路:使用一個類來代表一個節點 其中類中的屬性來表示節點中的內容

  • 添加(創建)
    • 先創建一個head節點,作用就是表示單鏈表的頭
    • 后面每添加一個節點,就直接加入到鏈表的最后
  • 遍歷
    • 通過一個輔助變量遍歷,幫助遍歷整個鏈表
class HeroNode{int no;String name;String nickName;HeroNode next;
}

在這里插入圖片描述

圖3 單鏈表的創建示意圖

2.1 直接將節點添加到鏈表尾部

實現添加節點時,直接添加到鏈表尾部

public class SingleLinkedListDemo {public static void main(String[] args) {//進行測試//先創建節點HeroNode heroNode1 = new HeroNode(1, "松江", "及時雨");HeroNode heroNode2 = new HeroNode(2, "盧俊義", "玉麒麟");HeroNode heroNode3 = new HeroNode(3, "吳用", "智多星");HeroNode heroNode4 = new HeroNode(4, "林沖", "豹子頭");//創建一個列表SingleLinkedList singleLinkedList = new SingleLinkedList();//加入singleLinkedList.add(heroNode1);singleLinkedList.add(heroNode2);singleLinkedList.add(heroNode3);singleLinkedList.add(heroNode4);//顯示singleLinkedList.list();}
}//定義SingleLinkedList管理節點
class SingleLinkedList {//先初始化一個頭節點 頭節點不要動 不存放具體的數據private HeroNode head = new HeroNode(0, " ", " ");//添加節點到單向鏈表//思路,當不考慮編號順序時//1. 找到當前鏈表的最后節點//2. 將最后這個節點的next 指向 新的節點public void add(HeroNode heroNode) {//因為head節點不能動 因此需要一個輔助變量tempHeroNode temp = head;//遍歷鏈表 找到最后while (true) {//鏈表的最后一個節點的next為nullif (temp.next == null) {//說明此時temp就指向了鏈表的最后temp.next = heroNode;break;} else {temp = temp.next;//將此節點的下一個節點作為新循環的判斷(后移一個節點判斷)}}}//顯示鏈表[遍歷]public void list() {//判斷鏈表是否為空if (head.next == null) {System.out.println("鏈表為空");return;}//因為head節點不能動 因此需要一個輔助變量temp來遍歷HeroNode temp = head.next;while (true) {//輸出節點信息System.out.println(temp);//判斷是否到鏈表最后if (temp.next == null) {//說明這個節點是最后一個節點break;}temp = temp.next;//后移一個節點}}
}//定義HeroNode,每個HeroNode對象就是一個節點
class HeroNode {public int no;public String name;public String nickname;public HeroNode next;   //指向下一個節點//構造器public HeroNode(int no, String name, String nickname) {this.no = no;this.name = name;this.nickname = nickname;}@Overridepublic String toString() {return "HeroNode{" +"no=" + no +", name='" + name + '\'' +", nickname='" + nickname + '\'' +", next=" + (next == null ? null : next.hashCode()) +'}';}
}

2.2 按順序添加節點

實現添加節點時,根據排名將英雄插入到指定位置(如果有這個排名,則添加失敗,并給出提示)

在這里插入圖片描述

圖4 按順序添加節點示意圖

需要按照編號的順序添加節點 思路:

  1. 首先找到新添加的節點的位置,是通過輔助變量(指針),通過遍歷來搞定
  2. 新的節點.next = temp.next
  3. 將 temp.next = 新的節點

自己寫代碼如下,重寫了一下類

//定義SingleLinkedList2按順序管理節點
class SingleLinkedList2 {//先初始化一個頭節點 頭節點不要動 不存放具體的數據private HeroNode head = new HeroNode(0, " ", " ");//按順序添加節點到單向鏈表public void add(HeroNode heroNode) {if (head.next == null) {//說明此時空鏈表head.next = heroNode;//直接將此節點添加到頭節點的后面return;}HeroNode temp = head;do {if (heroNode.no < temp.next.no) {//將此節點插入到temp和temp.next中間
//                HeroNode temp2 = temp.next;//保存temp的下一個節點
//                temp.next = heroNode;     //將temp下一行節點指向heroNode
//                heroNode.next = temp2;    //將heroNode的下一個節點指向到原temp.nextheroNode.next = temp.next;  //將heroNode的下一個節點指向到temp.nexttemp.next = heroNode;       //將temp下一行節點指向heroNodereturn;  //直接結束戰斗} else if (heroNode.no == temp.next.no) {System.out.println("已經當有相同節點了 添加失敗 請自重");return;}temp = temp.next; //節點后移} while (temp.next != null);//如果正常退出 說明此對象的序號值最大 直接放在最后面temp.next = heroNode;}//顯示鏈表[遍歷]public void list() {if (head.next == null) {System.out.println("別鬧寶 空鏈表~~");return;}HeroNode temp = head;while (temp.next != null) {//如果下一個節點不為空(存了數據)System.out.println(temp.next);  //輸出下一個節點temp = temp.next;   //后移到下一個節點}}
}

韓老師教的如下 在SingleLinkedList類中新添加了一個按順序排列的函數

//第二種方式在添加英雄時 根據排名將英雄插入到指定位置
//(如果有這個排名 則添加失敗 并給出提示)
public void addByOrder(HeroNode heroNode) {//因為頭節點不能動 因此我們仍然通過一個輔助指針(變量)來幫助找到添加的位置//因為是單鏈表 找的temp是位于添加位置的前一個節點 否則插入不了HeroNode temp = head;boolean flag = false;   //標志添加的編號是否存在 默認為falsewhile (true) {if (temp.next == null) {//說明temp已經在鏈表的最后break;}if (temp.next.no > heroNode.no) { //位置找到 就在temp的后面插入break;} else if (temp.next.no == heroNode.no) {  //說明希望添加的heroNode的編號已經存在flag = true;    //說明編號存在break;}temp = temp.next;   //后移一位 相當于遍歷鏈表}//判斷flag的值if(flag){   //不能添加 說明編號存在System.out.printf("準備插入的英雄的編號 %d 已經存在了,不能加入\n",heroNode.no);} else {//因為不管是temp.next == null還是temp.next.no > heroNode.no 都需要把heroNode放在temp的后面//加入到鏈表中 temp的后面heroNode.next = temp.next;temp.next = heroNode;}
}

2.3 單鏈表節點的修改(根據no編號來修改)

自己寫的如下 在類中增加了一個修改函數

//修改節點的信息 根據no編號來修改 即no編號不能改
public void modify(int no, String name,String nickname) {if (head.next == null) {//說明此時空鏈表System.out.println("空鏈表 修改失敗 改不了");return;}HeroNode temp = head;while (temp.next != null){  //遍歷if(no == temp.next.no){ //如果編號相同temp.next.name = name;temp.next.nickname = nickname;return;//結束函數}temp = temp.next;}//如果正常退出循環 則說明沒找到對應的編號System.out.println("不好意思,沒找到對應編號的位置");
}

韓老師寫的如下

//修改節點的信息,根據no編號來修改 即no編號不能改
//說明
//1. 根據newHeroNode 的 no 來修改即可
public void update(HeroNode newHeroNode){//判斷是否為空if(head.next == null){System.out.println("鏈表為空");return;}//找到需要修改的節點 根據no編號//定義一個輔助變量HeroNode temp = head.next;boolean flag = false;//表示是否找到該節點while (true){if(temp == null){break;//已經遍歷完鏈表}if(temp.no == newHeroNode.no){//找到flag = true;break;}temp = temp.next;}//根據flag 判斷是否找到要修改的節點if(flag){temp.name = newHeroNode.name;temp.nickname = newHeroNode.nickname;}else {//沒有找到System.out.println("修改失敗 沒有找到");}
}

2.4 單鏈表節點的刪除

自己寫的代碼如下

//節點的刪除 根據no編號來刪除
public void delete(int no){if (head.next == null) {//說明此時空鏈表System.out.println("空鏈表 刪除失敗 請自重寶~~");return;}HeroNode temp = head;while (temp.next != null){if(temp.next.no == no){temp.next = temp.next.next; //將temp指向后移兩位return;//結束函數}temp = temp.next;//后移一位}//正常退出while 則說明沒找到對應的編號System.out.println("沒找到對應的編號");
}

韓老師思路如下

  1. 從單鏈表中刪除一個節點的思路
  2. temp.next = temp.next.next
  3. 被刪除的節點 將不會有其它引用 會被垃圾回收機制回收

在這里插入圖片描述

圖5 單鏈表刪除示意圖

代碼如下

//刪除節點
//思路
//1. head 不能動 因此我們需要一個temp輔助找到帶刪除節點的前一個節點
//2. 說明在比較時 是temp.next.no 和 需要刪除的節點的no比較
public void del(int no){HeroNode temp = head;boolean flag = false;   //標志是否找到待刪除節點的while (true){if(temp.next == null){  //已經到鏈表的最后break;}if(temp.next.no == no){//找到待刪除節點的前一個節點tempflag = true;break;}temp = temp.next;   //temp后移 遍歷}if(flag){//找到//可以刪除temp.next = temp.next.next;}else {System.out.println("要刪除的節點不存在");}
}

3. 單鏈表面試題

3.1 求單鏈表中節點的個數(不統計頭節點)

其中就是遍歷一遍即可

3.2 查找單鏈表中的倒數第k個節點

//查找單鏈表中倒數第k個節點
//思路
//1. 編寫一個方法 接收head節點 同時接收一個index
//2. index 表示是倒數第index個節點
//3. 先把鏈表從頭到尾遍歷,得到鏈表的總長度
//4. 得到size后,從鏈表的第一個開始遍歷(size - index)個 就可以得到
//5. 找到則返回該節點 否則返回null
public static HeroNode findLastIndexNode(HeroNode head, int index) {//判斷如果鏈表為空 返回nullif (head.next == null) {return null;    //沒有找到}//第一次遍歷得到鏈表的長度int size = getLength(head);//第二次遍歷 size - index + 1位置 就是倒數的第k個節點//先做一個index的校驗if (index <= 0 || index > size) {return null;}//定義一個輔助變量HeroNode temp = head.next;for (int i = 0; i < size - index; i++) {temp = temp.next;}return temp;
}

3.3 單鏈表的反轉

按照自己寫的如下 思路就是每一次分別找到原鏈表中第size - i 個節點即新鏈表中第i個節點(包含頭節點),然后進行連接

    public static void reverse(HeroNode head) {if (head.next == null) {//判斷如果鏈表為空return;    //沒有找到}//第一次遍歷得到鏈表的長度int size = getLength(head);HeroNode temp1 = null;HeroNode temp2 = null;HeroNode temp3 = head.next; //保存好原鏈表的第一個節點for (int i = 0; i < size; i++) {temp1 = temp3;for (int j = 0; j < size - i - 1; j++) {    //每個大循環依次從原鏈表中得到最后一個到第一個節點temp1 = temp1.next;}
//            System.out.println(temp1);temp2 = head;for (int j = 0; j < i; j++) {   //每個大循環依次從新鏈表得到頭節點到最后第二個節點temp2 = temp2.next;}
//            System.out.println(i + " " + temp1 + " " + temp2);temp2.next = temp1; //重新將節點連接起來}temp3.next = null;  //切記 別忘了把新鏈表的最后一個(原鏈表的第一個)的next置null}

韓老師的思路:

  1. 先定義一個節點 reverseHead = new HeroNode();
  2. 從頭到尾遍歷原來的鏈表,每遍歷一個節點,就將其取出,并放在新的鏈表reverseHead的最前端
  3. 原來的鏈表的head.next=reverseHead.next;
//將單鏈表反轉
public static void reverseList(HeroNode head){//如果當前鏈表為空 或者只有一個節點 無需反轉 直接返回if(head.next == null || head.next.next == null){return;}//定義一個輔助指針(變量) 幫助遍歷原來的鏈表HeroNode cur = head.next;HeroNode next = null;   //指向當前節點[cur]的下一個節點HeroNode reverseHead = new HeroNode(0,"","");//遍歷原來的鏈表 每遍歷一個節點 就將其取出 并放在新的鏈表reverseHead的最前面while (cur != null){next = cur.next;	//保存原鏈表中的下一個節點 cur.next = reverseHead.next; //先讓此節點的next域指向新鏈表的首位reverseHead.next = cur;     //再將新鏈表的頭部指向此節點 實現cur節點插入cur = next;     //再將該cur引用重新指向原鏈表沒有進行操作的節點}//將head.next 指向reverseHead.next 實現單鏈表的反轉head.next = reverseHead.next;
}

不得不說啊,這韓老師就是牛啊,短短幾行代碼就搞定了!!!其實就類似于插入,將原鏈表的節點按順序插入到新鏈表的頭部與第一個節點之間,此節點就作為新鏈表的第一個節點。那么最后原鏈表中的第i個節點就依次排到新鏈表中的size-i個節點中了。

3.4 從尾到頭打印單鏈表

【方式一:反向遍歷 方式二:Stack棧】

3.4.1 逆序輸出 反向遍歷

韓老師沒演示這種 自己寫的如下

//遍歷逆序輸出 
public static void reverseOutput(HeroNode head){if (head.next == null) {//判斷如果鏈表為空return;    //沒有找到}//第一次遍歷得到鏈表的長度int size = getLength(head);HeroNode temp1 = null;for (int i = 0; i < size; i++) {temp1 = head.next;for (int j = 0; j < size - i - 1; j++) {    //每個大循環依次從原鏈表中得到最后一個到第一個節點temp1 = temp1.next;}System.out.println(temp1);}
}
//遞歸逆序輸出
public static void reverseOutputDiGui(HeroNode head){if(head.next==null){//說明到頭了}else {reverseOutputDiGui(head.next);}if(head.no != 0){System.out.println(head);}
}
3.4.2 Stack棧

韓老師思路如下

  • 可以利用棧這個數據結構,將各個節點壓入到棧中 然后利用棧的先進后出的特點 就實現了逆序打印的效果

    /*** @author 小小低頭哥* @version 1.0* 演示Stack的使用*/
    public class TestStack {public static void main(String[] args) {Stack<String> stack = new Stack<>();//入棧stack.add("jack");stack.add("tom");stack.add("smith");//出棧while (stack.size() > 0){System.out.println(stack.pop());//POP就是將棧頂的數據取出}}
    }
    
    //逆序輸出
    //利用棧這個數據結構,將各個節點壓入到棧中 然后利用棧的先進后出的特點 就實現了逆序打印的效果
    public static void reversePrint(HeroNode head){if (head.next == null) {//判斷如果鏈表為空return;    //空鏈表 不能打印}//創建一個棧 將各個節點壓入棧Stack<HeroNode> stack = new Stack<>();HeroNode cur = head.next;//將鏈表的所有節點壓入棧while (cur != null){stack.push(cur);    //入棧cur = cur.next; //后移}//將戰中節點打印while (stack.size() > 0){System.out.println(stack.pop());    //出棧 先進后出}
    }
    

3.5 合并兩個有序的單鏈表,合并之后的鏈表依然有序

自己苦戰出來的,試過輸入沒毛病的情況下 ,結果還可以

思路:
以鏈表一為基準,遍歷鏈表一的每一個節點。在遍歷每個鏈表一的節點期間,將鏈表二中節點編號依次與此時遍歷的鏈表一中 的節點編號進行比較,滿足條件的則接在新鏈表的最后一個節點上。由于是鏈表一二都是順序排列,所以一旦鏈表二中節點編號有不滿足條件的,則將此時鏈表一中遍歷的節點接在新鏈表的最后一個節點上,并跳出遍歷鏈表二的循環,繼續遍歷鏈表一中的下一個節點,再接著上次鏈表二中第一個不滿足的節點進行比較(注意不是重新與鏈表二中的節點一個個比較)。以此循環。

/*** 合并兩個有序鏈表* 但是要確保輸入的兩個鏈表都是從小到大排序的 否則需要if(temp2.no <= temp1.no)中的 <= 換成 >=* @param head1* @param head2* @return 合并后的鏈表*/
public static HeroNode mergeList(HeroNode head1, HeroNode head2) {HeroNode newHero = new HeroNode(0," "," ");//新建一個節點HeroNode end = newHero;   //保存newHero最后一個節點HeroNode temp1 = head1.next; //鏈表一指針HeroNode temp2 = head2.next; //鏈表二指針HeroNode next = null;   //保存下一個節點while (true){//以鏈表一進行順序遍歷while (true){//當鏈表二中有節點的no 小于鏈表一中的當前節點的no時if(temp2.no <= temp1.no){ //從小到大排序next = temp2.next;end.next = temp2;//將temp2插入到newHero最后end = end.next; //將end后移一個temp2 = next;   //將temp2指向鏈表二的下一個節點繼續與temp1比較}else {next = temp1.next;end.next = temp1;//將temp1插入到newHero最后end = end.next; //將end后移一個if(next == null){ //說明temp1比較完了 直接把temp2插入到newHero最后end.next = temp2;return newHero;}temp1 = next;   //沒比較完 則temp1后移break;  //結束鏈表二中的節點與鏈表一中temp1節點的比較(因為是有序的 所以鏈表二后面的肯定也不符合條件)}if(temp2 == null){//說明鏈表二中的節點都比較完畢 那么直接把鏈表一中剩下的節點temp1連接上新鏈表即可end.next = temp1;return newHero;}}}
}

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

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

相關文章

滑動窗口練習(三)— 加油站問題

題目 測試鏈接 在一條環路上有 n 個加油站&#xff0c;其中第 i 個加油站有汽油 gas[i] 升。 你有一輛油箱容量無限的的汽車&#xff0c;從第 i 個加油站開往第 i1 個加油站需要消耗汽油 cost[i] 升。你從其中的一個加油站出發&#xff0c;開始時油箱為空。 給定兩個整數數組…

如何教會小白使用淘寶API接口獲取商品數據

隨著互聯網的普及&#xff0c;越來越多的人開始接觸網絡購物&#xff0c;而淘寶作為中國最大的電商平臺之一&#xff0c;成為了眾多消費者首選的購物平臺。然而&#xff0c;對于一些小白用戶來說&#xff0c;如何通過淘寶API接口獲取商品數據可能是一個難題。本文將詳細介紹如何…

Python學習之——時間和日期

Python學習之——時間模塊 參考time 模塊常見接口 datetime 模塊常見接口 calendar 模塊常見接口 示例 參考 Python datetime模塊詳解、示例 搞定Python時區的N種姿勢 calendar – 日歷相關 time 模塊 在Python中&#xff0c;通常有這幾種方式來表示時間&#xff1a; 1&…

浮點數在計算機中如何存儲

舉例&#xff1a; 結果&#xff1a; 文字描述&#xff1a; 先將浮點數轉化為二進制的表示形式&#xff0c; 接著將其二進制的形式按照科學計數法來表示&#xff0c; 符號位的確定&#xff1a;正數0&#xff0c; 負數1 指數的確定&#xff1a;將其二進制表示成為科學計數法…

Fall in love with English

Fall in love with English 愛上英語 Hiding behind the loose dusty curtain, a teenager packed up his overcoat into the suitcase. 躲藏在布滿塵土的松軟的窗簾后邊&#xff0c;一個年輕人打包他的外套到行李箱中。 He planned to leave home at dusk though there was th…

超完整的mysql安裝配置方法(包含idea和navicat連接mysql,并實現建表)

mysql安裝配置方法 1、下載mysql2、解壓到指定的安裝目錄3、配置初始化文件my.ini4、配置用戶變量和系統變量5、初始化mysql6、安裝mysql服務并啟動修改密碼7、使用idea連接mysql8、使用Navicat可視化工具連接mysql&#xff0c;并實現新建數據庫&#xff0c;新建表 1、下載mysq…

計算機考研408-計算機網絡、操作系統整書知識點腦圖

計算機網絡、操作系統整書知識點腦圖 今天突然想起來考研期間為了方便記憶&#xff0c;費了很大力氣整理了計算機網絡、操作系統兩本書知識點的腦圖&#xff0c;想著放著也沒啥用&#xff0c;分享出來給大家看看 但是思維導圖格式的東西好像沒法直接發成文章&#xff0c;上傳…

【NodeJs】UniSMS 實現短信驗證碼

承接上文 &#xff0c;上次用的是 短信寶平臺 認證已經通過 后續又新增要求 平臺相當麻煩&#xff01; 短信寶實現短信發送要求&#xff1a; 1.平臺綁定手機號 必須和 營業執照法人一致 2.平臺個人實名認證 必須和 營業執照法人一致 3.平臺需要上傳營業執照 4.平臺需要上…

拒接服務攻擊(DOS)的初步介紹

文章目錄 什么是拒絕服務攻擊拒絕服務攻擊的過程拒絕服務攻擊的類型常見的拒絕服務攻擊如何防范拒絕服務攻擊分布式拒絕服務攻擊&#xff08;DDoS&#xff09; 什么是拒絕服務攻擊 拒絕服務攻擊是一種網絡攻擊方式&#xff0c;攻擊者通過向目標計算機系統或網絡發送大量的請求…

免費分享一套Springboot+Vue前后端分離的在線商城系統,挺實用的

大家好&#xff0c;我是java1234_小鋒老師&#xff0c;看到一個不錯的SpringbootVue前后端分離的在線商城系統&#xff0c;分享下哈。 項目視頻演示 【免費】SpringbootVue在線商城系統 畢業設計 Java畢業設計_嗶哩嗶哩_bilibili【免費】springbootvue在線商城系統 畢業設計 …

97基于matlab的改進的帶記憶的模擬退火算法求解TSP問題

基于matlab的改進的帶記憶的模擬退火算法求解TSP問題&#xff0c;采用多普勒型降溫曲線描述迭代過程&#xff0c;在傳統算法的基礎上增加記憶功能&#xff0c;可測試中國31/64/144以及att48城市的數據&#xff0c;也可自行輸入數據進行測試&#xff0c;測試結果基本達到當前最優…

Swagger2的使用

手寫Api文檔的幾個痛點&#xff1a; 文檔需要更新的時候&#xff0c;需要再次發送一份給前端&#xff0c;也就是文檔更新交流不及時。 接口返回結果不明確 不能直接在線測試接口&#xff0c;通常需要使用工具&#xff0c;比如postman 接口文檔太多&#xff0c;不好管理 Sw…

gin投票項目4

對應視頻v2版本 gin項目投票系統4 1.增加一個注冊賬號的功能 增加接口 參數校驗&#xff1a;&#xff08;需求&#xff09; 確認密碼需要一致&#xff0c;不為空用戶名必須唯一, 不為空用戶名大于8小于16位密碼大于8小于16位,并且不能為純數字 正則表達式 必須知道這東西…

我對遷移學習的一點理解(系列2)

文章目錄 我對遷移學習的一點理解 我對遷移學習的一點理解 源域和目標域是相對的概念&#xff0c;指的是在遷移學習任務中涉及到的兩個不同的數據集或領域。 源域&#xff08;Source Domain&#xff09;通常指的是已經進行過訓練和學習的數據集&#xff0c;它被用來提取特征、…

Nginx緩存及HTTPS配置小記

緩存基礎 緩存分類 某些場景下&#xff0c;Nginx需要通過worker到上有服務中獲取數據并將結果響應給客戶端&#xff0c;在高并發場景下&#xff0c;我們完全可以將這些數據視為熱點數據&#xff0c;并將其緩存到Nginx服務上。 客戶端緩存&#xff1a;將緩存數據放到客戶端。 …

yolov8與yolov5網絡對比

回顧一下YOLOv5&#xff0c;不然沒機會了 這里粗略回顧一下&#xff0c;這里直接提供YOLOv5的整理的結構圖吧&#xff1a; Backbone&#xff1a;CSPDarkNet結構&#xff0c;主要結構思想的體現在C3模塊&#xff0c;這里也是梯度分流的主要思想所在的地方&#xff1b;PAN-FPN&…

OFDM模糊函數仿真

文章目錄 前言一、OFDM 信號及模糊函數1、OFDM 信號表達式2、模糊函數表達式 二、MATLAB 仿真1、MATLAB 核心源碼2、仿真結果①、OFDM 模糊函數②、OFDM 距離模糊函數③、OFDM 速度模糊函數 前言 本文進行 OFDM 的仿真&#xff0c;首先看一下 OFDM 的模糊函數仿真效果&#xf…

【vim】常用操作

用的時候看看&#xff0c;記太多也沒用&#xff0c;下面都是最常用的&#xff0c;更多去查文檔vim指令集。 以下均為正常模式下面操作&#xff0c;正在編輯的&#xff0c;先etc一下. 1/拷貝當前行 yy&#xff0c;5yy為拷貝包含當前行往下五行 2/p將拷貝的東西粘貼到當前行下…

Nmap腳本的應用場景

網絡安全檢測和漏洞掃描 Nmap腳本是一種強大的工具&#xff0c;可以用于網絡安全檢測和漏洞掃描。在滲透測試工程師的角度下&#xff0c;本文將詳細闡述Nmap腳本的應用場景&#xff0c;以及如何使用Nmap腳本進行網絡安全檢測和漏洞掃描。 一、Nmap腳本的應用場景 Nmap腳本在滲…

Java、JDK、JRE、JVM

Java、JDK、JRE、JVM 一、 Java 廣義上看&#xff0c;Kotlin、JRuby等運行于Java虛擬機上的編程語言以及相關的程序都屬于Java體系的一員。從傳統意義上看&#xff0c;Java社區規定的Java技術體系包括以下幾個部分&#xff1a; Java程序設計語言各種硬件平臺上的Java虛擬機實…