帶你玩轉數據結構-單鏈表(適合初學者的文章,講解的很仔細哦)

在這里插入圖片描述

前言:

🎈個人主頁:🎈 :???初階牛???
🐻推薦專欄: 🍔🍟🌯 C語言進階
🔑個人信條: 🌵知行合一
🍉本篇簡介:>:講解數據結構中鏈表的知識,;鏈表的分類,c語言實現單鏈表常見接口等.
金句分享:
?山不向我走來,我便向山走去.?

目錄

  • 前言:
  • 一、鏈表介紹
    • 1.1 鏈表結構圖:
    • 1.2 鏈表分類(圖解分析)
  • 二、單鏈表實現:
    • 2.1 鏈表的"結點"聲明:
    • 2.2 "插入"元素操作.
      • 單鏈表的"尾插":
      • 單鏈表的"頭插"
      • 指定位置之后"插入"新節點
      • "申請新節點"函數
    • 2.3 "刪除"元素操作.
      • 單鏈表的"尾刪"
      • 單鏈表的"頭刪":
      • 單鏈表的"刪除"指定的目標結點
    • 2.4 "查找"目標結點函數
    • 2.5 單鏈表的"打印"
    • 2.6 單鏈表的"銷毀"
    • 總結:"鏈表"與"順序表"的區別
  • 三、總代碼
    • 測試區(test.c)
    • 接口實現區(SList.c)
    • 函數聲明區(SList.h)

一、鏈表介紹

順序表缺點:

  1. 中間/頭部的插入刪除,時間復雜度為O(N),因為需要移動數據.
  2. 增容需要申請新空間,特別是異地擴容,拷貝數據,釋放舊空間。消耗不小。
  3. 增容不是一次增容到位,而是每次增容后判斷是否符合要求,并且增容一般是2倍增容,一次次擴容消耗太大.
  4. 除此之外,還可能有一定的空間浪費。
    例如:當前容量為200,如果有201個待插入數據,勢必要增容到400(原來容量的兩倍),這樣就浪費了199個空間.

我們不妨來看一下鏈表的存儲結構.

鏈表的概念:
概念:鏈表是一種物理存儲結構上非連續、非順序的存儲結構,數據元素的邏輯順序是通過鏈表中的指針鏈接次序實現的.也是屬于線性表的一種.

🌰栗子
單鏈表的結點聲明:

typedef int DateType;
typedef struct SListN0de
{DateType Date;//數據域struct SListN0de* next;//指針域
}SLTNode;

結點:

1.1 鏈表結構圖:

在這里插入圖片描述

通過上圖我們不難知道:

  1. 鏈表在邏輯上是連續的(next指針,指向下一個結點,鏈接在一起),而物理上可能連續,也可能不連續.
  2. 鏈表是由一個個結點鏈接在一起組成的,每個結點其實是malloc在堆區上申請的,所以地址可能連續,也可能不連續.

1.2 鏈表分類(圖解分析)

共有八種鏈表,我們主要學習不帶頭單向鏈表帶頭雙向鏈表,學會這兩種,其它的大同小異,寫起來并不苦難.
在這里插入圖片描述

單向、雙向:

在這里插入圖片描述

不帶頭、帶頭:
在這里插入圖片描述

帶頭與不帶頭的區別在于:
帶頭:鏈表是通過一個特殊的結點—頭結點指向鏈表的第一個有效結點.
不帶頭:通過結點指針指向鏈表的第一個有效結點.

頭結點作用:傳送門

不須換、循環:
在這里插入圖片描述

重點掌握:

  1. 無頭單向非循環鏈表(本篇重點):結構簡單,一般不會單獨用來存數據。實際中更多是作為其他數據結構的子結構,如哈希桶、圖的鄰接表等等。另外這種結構在筆試面試中出現很多,因為單鏈表不能回頭,可以考察的地方很多.
  2. 帶頭雙向循環鏈表:結構最復雜,一般用在單獨存儲數據。實際中使用的鏈表數據結構,都是帶頭雙向循環鏈表。這種結構的鏈表雖然結構復雜,但是優勢也很明顯,并且實現起來反而很簡單.后續跟著學到了就可以理解了.

在這里插入圖片描述

二、單鏈表實現:

2.1 鏈表的"結點"聲明:

typedef int DateType;
typedef struct SListN0de
{DateType Date;//數據域struct SListN0de* next;//指針域
}SLTNode;

單鏈表初始化:
單鏈表是不需要初始化操作的,只需要創建一個結點指針就行.初始狀態:指針指向NULL.

頭指針:

SLTNode* plist=NULL;

2.2 "插入"元素操作.

我們需要插入數據時,只需要申請一個結點,將數據放入結點,然后將結點鏈接起來就行.

單鏈表的"尾插":

單鏈表的尾插步驟:

  1. 找尾:
    由于單鏈表的結點之間不一定是連續存儲的,不支持向順序表那樣的隨機訪問,需要通過遍歷才能找到目標結點.
  2. 將最后一個結點的next指向新節點.

圖解:
在這里插入圖片描述
那如果鏈表本身就是空鏈表呢?
此時需要修改頭指針,將頭指針指向這個新節點.

注意:

  1. 需要傳二級指針:
    這點很重要,因為需要修改頭指針,而頭指針的類型是:SLTNode*,相信友友們學到這里應該知道,如果想要在函數中形參的改變影響實參,則需要傳址調用,通過地址來影響實參.
    那么,指針的地址是?二級指針相信友友們應該沒有忘記.😂😂😂

  2. 斷言,這里需要靈活斷言.

在這里插入圖片描述

"尾插"函數聲明:

void PushBack(SLTNode** pphead, DateType x)

pphead需要斷言:
pphead是指向 *pphead(一級指針/頭指針)的指針,即值存儲的是頭指針的地址,只要頭指針存在,則不為空.而頭指針一定存在.

*phead不能斷言:
*phead是頭指針,頭指針在鏈表為空時,頭指針的值是NULL,所以不能斷言.
鏈表中有數據時,指向第一個結點,值是第一個結點的地址.

  1. 頭指針是很重要的一個指針,我們都是通過頭指針找到鏈表的,所以,除了頭插需要修改頭指針以外,其他插入都不能修改頭指針,所以我們需要創建一個臨時指針:SLTNode*tail = *pphead代替頭指針找尾.

代碼:

void PushBack(SLTNode** pphead, DateType x)
{assert(pphead);//如果頭指針的地址為NULL,則報錯.SLTNode*tail = *pphead;//創建一個指針代替頭指針遍歷SLTNode* newnode = BuyNode(x);//*pphead代表代表頭指針,phead表示頭指針的地址//如果*pphead指向NULL,說明為空鏈表if (*pphead == NULL){//這里可以使用tail代替*phead嗎?//不能,因為這里要改變的是,頭結點的指針,需要用二級指針(解引用)來改變*pphead = newnode;//空鏈表是將頭指針指向新節點}else{//找尾巴,畫圖解析//這里可以使用tail,是因為,要改變的是結構體的內容,只需要用結構體指針(解引用)就行while ( tail->next != NULL)//如果該節點的下一個節點是空指針則停止循環{tail = tail->next;}tail->next = newnode;//讓尾節點的next指向新節點.}
}

單鏈表的"頭插"

尾插是不是顯得有些麻煩?那我們試著看一下頭插.

頭插步驟:

  1. 創建一個新節點.
  2. 將新節點指向頭指針指向的結點.
  3. 更新頭指針(頭指針指向新節點)

圖解:
在這里插入圖片描述
代碼實現:

//寫法1
void PushFront(SLTNode** pphead, DateType x)
{assert(pphead);SLTNode* newnode = BuyNode(x);//下面兩句的順序不能變newnode->next = *pphead;*pphead = newnode;
}

寫法2:

//寫法2
void PushFront(SLTNode** pphead, DateType x)
{assert(pphead);SLTNode* newnode = BuyNode(x);SLTNode* phead = *pphead;//創建一個臨時指針,保存一下頭指針指向的頭結點.//順序隨便改*pphead = newnode;newnode->next = phead;
}

兩種方法都比較好理解,也很簡單,單鏈表的頭插效率很高,不需要遍歷,

指定位置之后"插入"新節點

該函數很簡單,只需要通過查找目標結點函數找到目標結點的位置,然后將將新節點鏈接上去就行了.

步驟:

  1. 將新節點的指針域(next)指向指定結點的下一個結點.
  2. 將指定位置的結點的指針域(next)指向新節點,

圖解:
在這里插入圖片描述

//使用此函數之前可以先使用,查找目標結點函數(SListFind),找到位置先
void SLTInsertBack( SLTNode* pos, DateType x)
{assert(pos);SLTNode* newnode = BuyNode(x);newnode->next = pos->next;pos->next = newnode;
}

"申請新節點"函數

新節點都是使用malloc函數動態申請的.函數實現很簡單,相信聰明的友友們可以理解,牛牛就不過介紹了.

SLTNode* BuyNode(DateType x)//創建新結點
{SLTNode* newnode = (SLTNode*)malloc(sizeof(SLTNode));assert(newnode);//防止申請結點失敗newnode->Date = x;newnode->next = NULL;return newnode;
}

2.3 "刪除"元素操作.

因為鏈表的結點都是動態申請的,所以鏈表的刪除操作需要將目標結點釋放,同時為了保護原有的鏈表結構,需要將受目標結點的其他結點也靈活修改.

單鏈表的"尾刪"

"刪除結點"步驟:

  1. 處理特殊情況,如果頭指針指向NULL,空鏈表不能執行刪除操作.
  2. 找倒數第二個結點,方法:tail->next->next != NULL因為最后一個結點的next=NULL;
    數據結構記得多畫圖哦,有助于我們理解.
  3. 先釋放尾結點(tail->next),再將倒數第二個結點的next置空NULL
  4. 處理特殊情況:如果鏈表就只有一個結點,就不存在倒數第二個結點,此時直接釋放頭結點,并將頭結點置空.

圖解:
在這里插入圖片描述

//尾刪
void PopBack(SLTNode** pphead)
{assert(pphead);//二級指針不可能為空,如果為空就一定是傳錯了assert(*pphead);//防止空鏈表的刪除操作SLTNode* tail = *pphead;//創建一個指針代替頭指針遍歷if (tail->next == NULL) {free(tail);tail= NULL;}else {while (tail->next->next != NULL){tail = tail->next;}free(tail->next);tail->next = NULL;}}

單鏈表的"頭刪":

同樣,單鏈表的"頭刪"也是很簡單的操作.
步驟:

  1. 將頭結點記錄一下.
  2. 將頭指針指向第二個結點.
  3. 釋放頭結點.
void PopFront(SLTNode** pphead)
{assert(pphead);//二級指針不可能為空,如果為空就一定是傳錯了assert(*pphead);//防止空鏈表的刪除操作SLTNode* head = *pphead;*pphead = ( * pphead)->next;free(head);
}

思考:
需不需要單獨去考慮,如果鏈表只有一個結點的特殊情況?
在這里插入圖片描述
答案:

不需要,因為如果鏈表只有一個結點,頭刪頭指針指向第二個結點,剛好是指向NULL,也是符合要求的.

單鏈表的"刪除"指定的目標結點

步驟:

  1. 通過查找目標結點函數SListFind(下面牛牛講了),找到目標結點的地址.
  2. 將目標結點的前驅結點指向目標結點的后繼結點.
  3. 釋放目標結點.
  4. 特殊情況:如果是頭刪,需要修改頭結點,讓其指向第二個結點.

圖解:
在這里插入圖片描述

代碼實現:

//告訴位置(建議配合SListFind函數一起使用),刪除第一個出現該值的節點
void SlitErase(SLTNode** pphead, SLTNode* pos)
{assert(pphead);//二級指針不可能為空,如果為空就一定是傳錯了assert(*pphead);//防止空鏈表的刪除操作assert(pos);SLTNode* cur = *pphead;//創建一個指針代替頭指針遍歷if (cur == pos) {//如果目標結點是頭結點這種特殊情況SLTNode* next = cur->next;free(cur);*pphead = next;}else {while (cur->next != pos && cur->next != NULL)//遍歷尋找目標結點{cur = cur->next;}cur->next = pos->next;//將目標結點的前驅指向目標結點的后繼free(pos);}
}

2.4 "查找"目標結點函數

單鏈表查找目標結點只需要遍歷一遍這個鏈表即可,如果目標結點有多個,則只返回第一個遇到的目標結點,找不到目標結點則返回NULL.
函數很簡單,牛牛不過多介紹了.

SLTNode* SListFind(SLTNode* phead, DateType x)
{SLTNode* cur = phead;//代替頭指針遍歷鏈表while (cur){if (cur->Date == x){return cur;}cur = cur ->next;}return NULL;
}

2.5 單鏈表的"打印"

單鏈表的打印很簡單,遍歷打印就行了.

void Print(SLTNode* phead)//鏈表的打印
{//assert(phead);SLTNode* cur = phead;while (cur){printf("%d->", cur->Date);cur = cur->next;}printf("NULL\n\n");
}

2.6 單鏈表的"銷毀"

步驟:

  1. 創建next指針保存要刪除節點的下一個結點.
  2. 將要刪除的結點釋放.
  3. 將要刪除的結點更新到next
  4. 繼續執行1
//單鏈表的銷毀
void SLTDestroy(SLTNode* phead)//這個函數不會將頭指針置空,要使用該函數的人自己置空
{SLTNode* del = phead;SLTNode* next = phead;//用于記錄下一個結點while (next){next = next->next;free(del);del = next;}//保持習慣置空next == NULL;del = NULL;
}

總結:"鏈表"與"順序表"的區別

順序表鏈表區別
物理上必定是連續的邏輯上連續,但是物理上不一定連續物理存儲空間
訪問其中的某個結點支持隨機訪問( O(1) )不支持隨機訪問訪問元素
大多數情況下需要移動數據,效率低( O(N) )只需要改變目標指針的指向,但是需要找到該結點刪除和插入新節點(任意位置)
容量不夠時,動態順序表需要動態擴容,效率不高沒有容量的概念不需要擴容,資源利用率高插入數據時
元素的存儲很高效+頻繁訪問頻繁的對任意位置的插入和刪除使用場景
由于無物理上連續存在,利用率高利用率低緩存利用率

希望這篇文章對大家有幫助。歡迎小伙伴們私信提意見和提問哦!
最后,小伙伴們的點贊就是給牛牛最大的支持,能不能給牛牛來一個一鍵三連呢?謝謝支持。
在這里插入圖片描述

三、總代碼

測試區(test.c)

//test.c 主函數區域,用于測試接口
#include "SList.h"
void test1()
{SLTNode* plist=NULL;printf("插入0,1,2,3,4,5,6,7,8,9之后:\n");PushBack(&plist, 1);PushBack(&plist, 2);PushBack(&plist, 3);PushBack(&plist, 4);PushBack(&plist, 5);PushBack(&plist, 6);PushBack(&plist, 7);PushBack(&plist, 8);PushBack(&plist, 9);//頭插PushFront(&plist, 0);Print(plist);printf("尾刪一次后:\n");PopBack(&plist);Print(plist);printf("頭刪一次后:\n");PopFront(&plist);Print(plist);printf("刪除第一次出現元素7的結點后:\n");SlitErase(&plist, SListFind(plist, 7));Print(plist);printf("在第一個出現5值的結點后面插入一個值為666的結點\n");SLTInsertBack(SListFind(plist, 5), 666);Print(plist);SLTDestroy(plist);plist == NULL;
}
int main()
{test1();return 0;
}

接口實現區(SList.c)


#include "SList.h"SLTNode* BuyNode(DateType x)//創建新結點
{SLTNode* newnode = (SLTNode*)malloc(sizeof(SLTNode));assert(newnode);newnode->Date = x;newnode->next = NULL;return newnode;
}
void PushBack(SLTNode** pphead, DateType x)
{assert(pphead);SLTNode*tail = *pphead;//創建一個指針代替頭指針遍歷SLTNode* newnode = BuyNode(x);//cur代表代表頭指針,phead表示頭指針的地址//如果cur指向NULL,說明為空鏈表if (*pphead == NULL){//這里可以使用tail代替*phead嗎?//不能,因為這里要改變的是,頭結點的指針,需要用二級指針(解引用)來改變*pphead = newnode;//空鏈表是將頭指針指向新節點}else{//找尾巴,畫圖解析//這里可以使用tail,是因為,要改變的是結構體的內容,只需要用結構體指針(解引用)就行while ( tail->next != NULL){tail = tail->next;}tail->next = newnode;}
}//頭插(錯誤示例)
//void PushFront(SLTNode** pphead, DateType x)
//{
//	assert(pphead);
//	SLTNode* phead = *pphead;
//	SLTNode* newnode = BuyNode(x);
//	//下面兩句的順序不能變,除非再創一個結點保phead
//	newnode->next = phead;
//	phead= newnode;
//}
// 
正確寫法1
//void PushFront(SLTNode** pphead, DateType x)
//{
//	assert(pphead);
//	SLTNode* newnode = BuyNode(x);
//	//下面兩句的順序不能變,除非再創一個結點保phead
//	newnode->next = *pphead;
//	*pphead = newnode;
//}//寫法2
void PushFront(SLTNode** pphead, DateType x)
{assert(pphead);SLTNode* newnode = BuyNode(x);SLTNode* phead = *pphead;//順序隨便改*pphead = newnode;newnode->next = phead;
}
//尾刪
void PopBack(SLTNode** pphead)
{assert(pphead);//二級指針不可能為空,如果為空就一定是傳錯了assert(*pphead);//防止空鏈表的刪除操作SLTNode* tail = *pphead;//創建一個指針代替頭指針遍歷if (tail->next == NULL) {free(tail);tail= NULL;}else {while (tail->next->next != NULL){tail = tail->next;}free(tail->next);tail->next = NULL;}}
void PopFront(SLTNode** pphead)
{assert(pphead);//二級指針不可能為空,如果為空就一定是傳錯了assert(*pphead);//防止空鏈表的刪除操作SLTNode* head = *pphead;*pphead = ( * pphead)->next;free(head);
}SLTNode* SListFind(SLTNode* phead, DateType x)
{SLTNode* cur = phead;while (cur){if (cur->Date == x){return cur;}cur = cur ->next;}printf("找不到:\n");return NULL;
}
void SlitErase(SLTNode** pphead, SLTNode* pos)
{assert(pphead);//二級指針不可能為空,如果為空就一定是傳錯了assert(*pphead);//防止空鏈表的刪除操作assert(pos);SLTNode* cur = *pphead;//創建一個指針代替頭指針遍歷if (cur == pos) {//如果目標結點時頭結點SLTNode* next = cur->next;free(cur);*pphead = next;}else {while (cur->next != pos && cur->next != NULL)//遍歷尋找目標結點{cur = cur->next;}cur->next = pos->next;//將目標結點的前驅指向目標結點的后繼free(pos);}
}void SLTInsertBack( SLTNode* pos, DateType x)
{assert(pos);SLTNode* newnode = BuyNode(x);newnode->next = pos->next;pos->next = newnode;}void Print(SLTNode* phead)//鏈表的打印
{//assert(phead);SLTNode* cur = phead;while (cur){printf("%d->", cur->Date);cur = cur->next;}printf("NULL\n\n");
}void SLTDestroy(SLTNode* phead)//這個函數不會將頭指針置空,要使用該函數的人自己置空
{SLTNode* del = phead;SLTNode* next = phead;//用于記錄下一個結點while (next){next = next->next;free(del);del = next;}//保持習慣置空next == NULL;del = NULL;
}

函數聲明區(SList.h)

#pragma once
#include <stdio.h>
#include <assert.h>
#include <stdlib.h>
typedef int DateType;
typedef struct SListN0de
{DateType Date;struct SListN0de* next;
}SLTNode;//尾插
void PushBack(SLTNode** pphead, DateType x);
//尾刪
void PopBack(SLTNode** pphead);
//頭插
void PushFront(SLTNode** pphead, DateType x);
//頭刪
void PopFront(SLTNode** pphead);//告訴值,返回結點的地址
SLTNode* SListFind(SLTNode* phead, DateType x);//告訴位置(建議配合SListFind函數一起使用),刪除第一個出現該值的節點void SlitErase(SLTNode** pphead, SLTNode* pos);//告訴位置,在位置后面插入
void SLTInsertBack( SLTNode* pos, DateType x);struct SListN0de* BuyNode(DateType x);//創建新節點void Print(SLTNode* phead);//鏈表的打印// 單鏈表的銷毀
void SLTDestroy(SLTNode* phead);

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

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

相關文章

重學Springboot3-@import注解的作用

重學Springboot3-import注解的作用 1. 引言2. Import 注解的基本用法3. 導入多個配置類4. 使用 Import 導入組件5. 使用 ImportSelector 和 ImportBeanDefinitionRegistrar6. 總結 1. 引言 在 Spring Framework 中&#xff0c;Import 注解是一個重要的元注解&#xff0c;它允許…

Linux 定時備份文件到另一臺服務器

1. 需求 用戶要求將 Tomcat 的日志文件定時備份到另一臺服務器。同事給我提供了一個寫好的 java 框架&#xff0c;但實在不想給用戶再維護另一個服務了&#xff0c;所以另尋他法。 2. 問題 使用 scp 等跨服務器傳輸命令時需要手動輸入用戶名的密碼才可進行文件傳輸&#xff…

騰訊云幻獸帕魯服務器使用Linux和Windows操作系統的具體性能比較是什么?

騰訊云幻獸帕魯服務器使用Linux和Windows操作系統的具體性能比較是什么&#xff1f; 首先&#xff0c;從內核效率來看&#xff0c;Linux在同等硬件條件下的性能優于Windows。這是因為Linux內核設計簡潔&#xff0c;對服務器工作負載進行了優化&#xff0c;能夠更好地利用系統資…

機器學習:從理論到實踐

機器學習&#xff1a;從理論到實踐 摘要 機器學習是人工智能的一個核心領域&#xff0c;它使計算機能夠通過經驗來改進性能。本文將介紹機器學習的基本概念、主要算法以及如何在實際項目中應用這些算法。我們將通過Python代碼示例來演示如何使用機器學習庫scikit-learn進行數…

Python學習 day07(JSON)

JSON 各種編程語言存儲數據的容器不盡相同&#xff0c;在Python中有字典dict這樣的數據類型&#xff0c;而其他語言可能沒有對應的字典&#xff0c;為了讓不同的語言都能夠相互通用的傳遞數據&#xff0c;JSON就是一種非常良好的中轉數據格式&#xff0c;如下&#xff1a; JSON…

mTSL: netty單向/雙向TLS連接

創建證書 不管是單向tls還是雙向tls(mTLS)&#xff0c;都需要創建證書。 創建證書可以使用openssl或者keytool&#xff0c;openssl 參考 mTLS: openssl創建CA證書 單向/雙向tls需要使用到的相關文件: 文件單向tls雙向tlsServer端Client端備注ca.key----需要保管好&#xff0…

MySQL知識點歸納總結(二)

10、MVCC實現原理&#xff1f; 事務ID&#xff08;Transaction ID&#xff09;&#xff1a;每個事務在執行時都會被分配一個唯一的事務ID&#xff0c;用于標識該事務的開始時間順序。事務ID是一個遞增的整數&#xff0c;隨著每個新事務的開始而遞增。 Undo日志&#xff08;Un…

【Web安全靶場】sqli-labs-master 38-53 Stacked-Injections

sqli-labs-master 38-53 Stacked-Injections 其他關卡和靶場看專欄… 文章目錄 sqli-labs-master 38-53 Stacked-Injections第三十八關-報錯注入第三十九關-報錯注入第四十關-盲注第四十一關-盲注第四十二關-聯合報錯雙查詢注入第四十三關-報錯注入第四十四關-盲注第四十五關-…

「爬蟲職海錄」三鎮爬蟲

HI&#xff0c;朋友們好 「爬蟲職海錄」第三期更新啦&#xff01; 本欄目的內容方向會以爬蟲相關的“崗位分析”和“職場訪談”為主&#xff0c;方便大家了解一下當下的市場行情。 本欄目持續更新&#xff0c;暫定收集國內主要城市的爬蟲崗位相關招聘信息&#xff0c;有求職…

【高級數據結構】Trie樹

原理 介紹 高效地存儲和查詢字符串的數據結構。所以其重點在于&#xff1a;存儲、查詢兩個操作。 存儲操作 示例和圖片來自&#xff1a;https://blog.csdn.net/qq_42024195/article/details/88364485 假設有這么幾個字符串&#xff1a;b&#xff0c;abc&#xff0c;abd&…

Vue中如何實現條件渲染?

在Vue中實現條件渲染非常簡單且靈活&#xff0c;主要通過Vue的指令來實現。在Vue中&#xff0c;我們可以使用v-if和v-else指令來根據條件來渲染不同的內容。下面就讓我們通過一個簡單的示例來演示如何在Vue中實現條件渲染&#xff1a; <!DOCTYPE html> <html lang&qu…

GO泛型相關

通過引入 類型形參 和 類型實參 這兩個概念&#xff0c;我們讓一個函數獲得了處理多種不同類型數據的能力&#xff0c;這種編程方式被稱為 泛型編程。 2. Go的泛型 類型形參 (Type parameter)類型實參(Type argument)類型形參列表( Type parameter list)類型約束(Type constr…

Pake 輕松構建輕量級多端桌面應用

Pake 利用 Rust 輕松構建輕量級多端桌面應用&#xff0c;支持 Mac / Windows / Linux。 小白用戶&#xff1a;可以使用 「常用包下載」 方式來體驗 Pake 的能力&#xff0c;也可試試 Action 方式。 開發用戶&#xff1a;可以使用 「命令行一鍵打包」&#xff0c;對 Mac 比較友…

Matlab 機器人工具箱 動力學

文章目錄 R.dynR.fdynR.accelR.rneR.gravloadR.inertiaR.coriolisR.payload官網:Robotics Toolbox - Peter Corke R.dyn 查看動力學參數 mdl_puma560; p560.dyn;%查看puma560機械臂所有連桿的動力學參數 p560.dyn(2);%查看puma560機械臂第二連桿的動力學參數 p560.links(2)…

react父子組件傳參demo

父組件代碼 /* eslint-disable next/next/no-img-element */ "use client"; import React, { useEffect, useState } from "react"; import WxTip from ../components/WxTipconst Download () > {const [showTip, setshowTip] useState<boolean…

javaweb day9 day10

昨天序號標錯了 vue的組件庫Elent 快速入門 寫法 常見組件 復制粘貼 打包部署

高斯消元法解線性方程組

高斯消元法 基本性質&#xff1a; 把某一行乘一個非 0 0 0的數 (方程的兩邊同時乘上一個非 0 0 0數不改變方程的解) 交換某兩行 (交換兩個方程的位置) 把某行的若干倍加到另一行上去 &#xff08;把一個方程的若干倍加到另一個方程上去&#xff09; 算法步驟 枚舉每一列c …

洛谷p1225 c++(使用高精度)

題解: 一開始我這個代碼想到的是使用遞歸來求解 int digui(int n){int sum=0;if(n==1)sum=1;if(n==2)sum=2;if(n==1||n==2)return sum;if(n>2){return sum+=digui(n-1)+digui(n-2);} } 但是后面發現明顯超時,我試圖用記憶化搜索來搶救一下,所以就有了下面代碼 int di…

圖論 - DFS深度優先遍歷、BFS廣度優先遍歷、拓撲排序

文章目錄 前言Part 1&#xff1a;DFS&#xff08;深度優先遍歷&#xff09;一、排列數字1.題目描述輸入格式輸出格式數據范圍輸入樣例輸出樣例 2.算法 二、n皇后問題1.問題描述輸入格式輸出格式數據范圍輸入樣例輸出樣例 2.算法 三、樹的重心1.問題描述輸入格式輸出格式數據范圍…

計算機二級Python刷題筆記------基本操作題23、33、35、37(考察字符串)

文章目錄 第二十三題&#xff08;字符串替換&#xff1a;replace(old,new)&#xff09;第三十三題&#xff08;字符串遍歷&#xff09;第三十五題&#xff08;字符串與列表&#xff09;第三十七題&#xff08;拼接字符串&#xff09; 第二十三題&#xff08;字符串替換&#xf…