數據結構:鏈表

目錄

一.為什么要使用鏈表存儲數據?

二.鏈表的分類

單向或者雙向鏈表:

帶頭或者不帶頭:

循環或者非循環:

三.鏈表的實現

3.1無頭單向非循環鏈表的實現:

3.1.1單向無頭非循環鏈表的聲明

3.1.2動態申請一個節點

?3.1.3單鏈表打印

??3.1.4單鏈表尾插

???3.1.5單鏈表的頭插

???3.1.6單鏈表的尾刪

???3.1.7單鏈表頭刪

???3.1.8單鏈表查找

??3.1.9單鏈表在pos位置之前插入x

?3.1.10單鏈表在pos位置之后插入x

??3.1.11單鏈表刪除pos之后的值

?3.1.12單鏈表刪除pos位置的值

3.1.13銷毀單鏈表

?頭文件:

?測試文件:

3.2帶頭雙向循環鏈表的實現

3.2.1帶頭雙向循環鏈表的聲明

3.2.2動態申請一個節點

?3.2.3哨兵位初始化(創建鏈表的頭結點)

?3.2.4帶頭雙向循環鏈表打印

?3.2.5雙向鏈表尾插

??3.2.6雙向鏈表頭插

3.2.7雙線鏈表尾刪

3.2.8雙線鏈表頭刪

3.2.9雙向鏈表查找

?3.2.10雙向鏈表在pos的前面進行插入

3.2.11雙向鏈表刪除pos位置的結點

?3.2.12雙向鏈表銷毀

頭文件:

測試文件:

四.鏈表總結


一.為什么要使用鏈表存儲數據?

內存空間是所有程序的公共資源,在一個復雜的系統運行環境下,空閑的內存空間可能散落在內存各處。我們知道,存儲數組的內存空間必須是連續的,而當數組非常大時,內存可能無法提供如此大的連續空間。此時鏈表的靈活性優勢就體現出來了。

讓我們來看看鏈表的結構:

  • ?可以得出:鏈表是一種物理存儲結構上非連續、非順序的存儲結構,數據元素的邏輯順序是通過鏈表中的指針鏈接次序實現的 。
  • 上述圖中的鏈表知識鏈表中的其中一種

二.鏈表的分類

單向或者雙向鏈表:

帶頭或者不帶頭:

循環或者非循環:


雖然鏈表的種類很多,但我們主要使用的還是無頭單向非循環鏈表(OJ題中最常見的鏈表)和帶頭循環雙向鏈表(實踐應用)

三.鏈表的實現

3.1無頭單向非循環鏈表的實現:

對于項目我們需要區分測試文件和接口文件,這樣做有利于培養良好的代碼能力。

3.1.1單向無頭非循環鏈表的聲明

#pragma once
#include<stdio.h>
#include<stdlib.h>
#include<assert.h>typedef int SLNDataType;// 聲明一個  Single Link List Node (單向無頭鏈表)typedef struct SLLN
{//節點值SLNDataType val;//指向下一個節點的指針struct SLLN* next;}SLNode;

3.1.2動態申請一個節點

// 動態申請一個節點
SLNode* CreateNode(SLNDataType x)
{SLNode* newnode = (SLNode*)calloc(1, sizeof(SLNode));if (newnode == NULL){perror("calloc");//直接終止程序exit(-1);}newnode->val = x;newnode->next = NULL;return newnode;
}

?3.1.3單鏈表打印

// 單鏈表打印
void SLNodePrint(SLNode* plist)
{SLNode* cur = plist;if (cur != NULL){while (cur){printf("%d->", cur->val);cur = cur->next;}printf("NULL");printf("\n");}else{printf("鏈表為空無需打印\n");}
}

??3.1.4單鏈表尾插

// 單鏈表尾插
void SLNodePushBack(SLNode** pplist, SLNDataType x)
{//先創造一個新節點SLNode* newnode = CreateNode(x);SLNode* tail = *pplist;//將plist賦值給tail//找尾if (*pplist == NULL){*pplist = newnode;}else{while (tail->next != NULL){tail = tail->next;}tail->next = newnode;}
}

???3.1.5單鏈表的頭插

// 單鏈表的頭插
void SLNodePushFront(SLNode** pplist, SLNDataType x)
{//先創建一個新節點SLNode* newnode = CreateNode(x);newnode->next = *pplist;*pplist = newnode;
}

???3.1.6單鏈表的尾刪

// 單鏈表的尾刪
void SLNodePopBack(SLNode** pplist)
{//如果鏈表為空則不能刪除,報錯assert(*pplist);//找尾SLNode* tail = *pplist;//tail移動時我們還需要有一個前驅指針 prev 跟在tail后面SLNode* prev = NULL;//單鏈表只有一個節點情況下尾刪if (tail->next == NULL){free(*pplist);*pplist = NULL;}//單鏈表有多個節點情況下尾刪else{while (tail->next != NULL){prev = tail;tail = tail->next;}free(tail);tail = NULL;prev->next = NULL;}}

???3.1.7單鏈表頭刪

// 單鏈表頭刪
void SLNodePopFront(SLNode** pplist)
{//當鏈表為空時不能刪除,報錯assert(*pplist);SLNode* cur = *pplist;SLNode* newplist = (*pplist)->next;free(cur);cur = NULL;*pplist = newplist;}

???3.1.8單鏈表查找

// 單鏈表查找(配合在pos位置插入或者刪除使用)
SLNode* SLNodeFind(SLNode* plist, SLNDataType x)
{while (plist != NULL){if (plist->val == x){return plist;}else{plist = plist->next;}}return NULL;
}

??3.1.9單鏈表在pos位置之前插入x

//單鏈表在pos位置之前插入x
void SLNodeInsertBefore(SLNode** pplist, SLNode* pos, SLNDataType x)//此處傳入二級指針pplist是為了在頭插時改變plist的值,傳址調用
{//此處需要對哪個指針進行斷言檢查呢?assert(pos && *pplist);//防止人為亂傳空SLNode* cur = *pplist;SLNode* prev = NULL;//前驅指針prev保存cur前一個節點的地址if (pos == *pplist){//在頭節點位置前插入x實質上就是頭插,我們調用之前寫的頭插函數即可SLNodePushFront(pplist, x);}else{SLNode* newnode = CreateNode(x);while (cur != pos){prev = cur;cur = cur->next;}prev->next = newnode;newnode->next = cur;}
}

?3.1.10單鏈表在pos位置之后插入x

// 單鏈表在pos位置之后插入x
void SLNodeInsertAfter(SLNode* pos, SLNDataType x)
{//鏈表為空無法在pos位置之后插入xassert(pos);SLNode* newnode = CreateNode(x);if (newnode == NULL){perror(calloc);return;}SLNode* next = pos->next;pos->next = newnode;newnode->next = next;}

??3.1.11單鏈表刪除pos之后的值

//單鏈表刪除pos之后的值
void SLNodeEraseAfter(SLNode* pos)
{//鏈表為空無法刪除assert(pos);//當鏈表只剩下一個節點或者pos后面無節點時也無法刪除assert(pos->next);SLNode* del = pos->next;pos->next = pos->next->next;free(del);del == NULL;
}

?3.1.12單鏈表刪除pos位置的值

//單鏈表刪除pos位置的值
void SLNodeErasepos(SLNode** pplist, SLNode* pos)
{//鏈表為空不能刪除assert(*pplist);SLNode* cur = *pplist;SLNode* prev = NULL;//前驅指針prev保存cur前一個節點的地址if (pos != *pplist){while (cur != pos){prev = cur;cur = cur->next;}SLNode* next = cur->next;free(cur);cur = NULL;//鏈接兩個節點prev->next = next;}else{SLNode* next = cur->next;free(cur);cur = NULL;//更新頭節點*pplist = next;}
}

3.1.13銷毀單鏈表

//銷毀鏈表
void SLNodeDestory(SLNode** pplist)
{assert(pplist);assert(*pplist);SLNode* cur = *pplist;while (cur){SLNode* next = cur->next;free(cur);cur = next;}*pplist = NULL;
}

以上代碼為單鏈表所實現的所有功能(接口)


?頭文件:

#pragma once
#include<stdio.h>
#include<stdlib.h>
#include<assert.h>typedef int SLNDataType;// 聲明一個  Single Link List Node (單向無頭鏈表)typedef struct SLLN
{//節點值SLNDataType val;//指向下一個節點的指針struct SLLN* next;}SLNode;// 動態申請一個節點
SLNode* CreateNode(SLNDataType x);// 單鏈表打印
void SLNodePrint(SLNode* plist);// 單鏈表尾插
void SLNodePushBack(SLNode** pplist, SLNDataType x);// 單鏈表的頭插
void SLNodePushFront(SLNode** pplist, SLNDataType x);// 單鏈表的尾刪
void SLNodePopBack(SLNode** pplist);// 單鏈表頭刪
void SLNodePopFront(SLNode** pplist);// 單鏈表查找
SLNode* SLNodeFind(SLNode* plist, SLNDataType x);//單鏈表在pos位置之前插入x
void SLNodeInsertBefore(SLNode** pplist, SLNode* pos, SLNDataType x);//單鏈表在pos位置之后插入x
void SLNodeInsertAfter(SLNode* pos, SLNDataType x);//單鏈表刪除pos位置之后的值
void SLNodeEraseAfter(SLNode* pos);//單鏈表刪除pos位置的值
void SLNodeErasepos(SLNode** pplist, SLNode* pos);//銷毀單鏈表
void SLNodeDestory(SLNode** pplist);

?測試文件:

#define  _CRT_SECURE_NO_WARNINGS 1
#include"Single_linked_lists.h"//單鏈表尾插測試
void text1()
{SLNode* plist = NULL;SLNodePushBack(&plist, 1);SLNodePushBack(&plist, 2);SLNodePushBack(&plist, 3);SLNodePushBack(&plist, 4);SLNodePrint(plist);
}
//單向鏈表頭插測試
void text2()
{SLNode* plist = NULL;SLNodePushFront(&plist, 1);SLNodePushFront(&plist, 2);SLNodePushFront(&plist, 3);SLNodePushFront(&plist, 4);SLNodePrint(plist);}
//單向鏈表尾刪測試
void text3()
{//SLNode* plist = NULL;//SLNodePushBack(&plist, 1);//SLNodePushBack(&plist, 2);//SLNodePushBack(&plist, 3);//SLNodePushBack(&plist, 4);多節點尾刪測試//SLNodePopBack(&plist);SLNode* plist = NULL;SLNodePushBack(&plist, 1);//單節點尾刪測試SLNodePopBack(&plist);SLNodePrint(plist);
}
//單向鏈表頭刪測試
void text4()
{SLNode* plist = NULL;SLNodePushBack(&plist, 1);SLNodePushBack(&plist, 2);SLNodePushBack(&plist, 3);SLNodePushBack(&plist, 4);//頭刪測試SLNodePopFront(&plist);SLNodePrint(plist);
}//單向鏈表查找 val 測試
void text5()
{SLNode* plist = NULL;SLNodePushBack(&plist, 1);SLNodePushBack(&plist, 2);SLNodePushBack(&plist, 3);SLNodePushBack(&plist, 4);//查找val測試SLNode* pos = SLNodeFind(plist, 4);printf("%p\n", pos);
}// 單鏈表在pos位置之后插入 x 測試
void text6()
{SLNode* plist = NULL;SLNodePushBack(&plist, 1);SLNodePushBack(&plist, 2);SLNodePushBack(&plist, 3);SLNodePushBack(&plist, 4);//pos之后插入xSLNode* pos = SLNodeFind(plist, 3);SLNodeInsertAfter(pos, 0);SLNodePrint(plist);
}//單鏈表刪除pos之后的值測試
void text7()
{SLNode* plist = NULL;SLNodePushBack(&plist, 1);SLNodePushBack(&plist, 2);SLNodePushBack(&plist, 3);SLNodePushBack(&plist, 4);//單鏈表刪除pos之后的值測試SLNode* pos = SLNodeFind(plist, 3);SLNodeEraseAfter(pos);SLNodePrint(plist);}
//單鏈表在pos前一個位置插入 x 測試
void text8()
{SLNode* plist = NULL;SLNodePushBack(&plist, 1);SLNodePushBack(&plist, 2);SLNodePushBack(&plist, 3);SLNodePushBack(&plist, 4);SLNodePrint(plist);SLNode* posbefore = SLNodeFind(plist, 3);//單鏈表在pos前一個位置插入 x 測試SLNodeInsertBefore(&plist, posbefore, 0);SLNodePrint(plist);}
//單鏈表刪除pos位置的值
void text9()
{SLNode* plist = NULL;SLNodePushBack(&plist, 1);SLNodePushBack(&plist, 2);SLNodePushBack(&plist, 3);SLNodePushBack(&plist, 4);SLNodePrint(plist);//單鏈表刪除pos位置的值SLNode* pos1 = SLNodeFind(plist, 1);SLNode* pos2 = SLNodeFind(plist, 3);SLNodeErasepos(&plist, pos1);SLNodeErasepos(&plist, pos2);SLNodePrint(plist);}
int main()
{//text1();//單鏈表尾插測試//text2();//單向鏈表頭插測試//text3();//單向鏈表尾刪測試//text4();//單向鏈表頭刪測試//text5();//單向鏈表查找 val 測試//text6();// 單鏈表在pos位置之后插入 x 測試//text7();//單鏈表刪除pos之后的值測試//text8();//單鏈表在pos前一個位置插入 x 測試//text9();//單鏈表刪除pos位置的值測試return 0;
}

3.2帶頭雙向循環鏈表的實現

3.2.1帶頭雙向循環鏈表的聲明

#pragma once
#include<stdio.h>
#include<stdlib.h>
#include<assert.h>typedef int DataType;typedef struct ListNode
{DataType val;struct LTNode* next;struct LTNode* prev;
}LTNode;

3.2.2動態申請一個節點

//Create one newnode
LTNode* Createnode(DataType x)
{LTNode* newnode = (LTNode*)malloc(sizeof(LTNode));if (newnode == NULL){perror("malloc");exit(-1);}newnode->val = x;newnode->next = NULL;newnode->prev = NULL;return newnode;
}

?3.2.3哨兵位初始化(創建鏈表的頭結點)

//哨兵位初始化(創建鏈表的頭結點)
LTNode* LTInit()
{LTNode* plist = Createnode(-1);plist->next = plist;plist->prev = plist;return plist;
}

?3.2.4帶頭雙向循環鏈表打印

//帶頭雙向循環鏈表打印
void LTPrint(LTNode* plist)
{assert(plist);LTNode* cur = plist->next;printf("哨兵位<=>");while (cur != plist){printf("%d<=>", cur->val);cur = cur->next;}printf("\n");
}

?3.2.5雙向鏈表尾插

// 雙向鏈表尾插
void LTNodePushBack(LTNode* plist, DataType x)
{LTNode* newnode = Createnode(x);LTNode* tail = plist->prev;tail->next = newnode;newnode->prev = tail;plist->prev = newnode;newnode->next = plist;}

??3.2.6雙向鏈表頭插

// 雙向鏈表頭插
void LTNodePushFront(LTNode* plist, DataType x)
{assert(plist);LTNode* first = plist->next;LTNode* newnode = Createnode(x);newnode->next = first;first->prev = newnode;plist->next = newnode;newnode->prev = plist;}

3.2.7雙線鏈表尾刪

// 雙向鏈表尾刪
void LTNodePopBack(LTNode* plist)
{//防止鏈表不存在assert(plist);//防止鏈表為空assert(plist->next);LTNode* tail = plist->prev;plist->prev = tail->prev;LTNode* tailprev = tail->prev;tailprev->next = plist;
}

3.2.8雙線鏈表頭刪

// 雙向鏈表頭刪
void LTNodePopFront(LTNode* plist)
{//防止鏈表不存在assert(plist);//防止鏈表為空assert(plist->next);LTNode* first = plist->next;LTNode* second = first->next;plist->next = second;second->prev = plist;free(first);first = NULL;}

3.2.9雙向鏈表查找

// 雙向鏈表查找
LTNode* LTNodeFind(LTNode* plist, DataType x)
{//防止鏈表不存在assert(plist);//防止鏈表為空assert(plist->next);LTNode* cur = plist->next;while (cur != plist){if (cur->val == x){return cur;}cur = cur->next;}return NULL;
}

?3.2.10雙向鏈表在pos的前面進行插入

// 雙向鏈表在pos的前面進行插入
void LTNodeInsert(LTNode* pos, DataType x)
{assert(pos);LTNode* newnode = Createnode(x);LTNode* posprev = pos->prev;posprev->next = newnode;newnode->next = pos;pos->prev = newnode;newnode->prev = posprev;
}

3.2.11雙向鏈表刪除pos位置的結點

// 雙向鏈表刪除pos位置的結點
void LTNodeErase(LTNode* pos)
{//防止傳空assert(pos);LTNode* posnext = pos->next;LTNode* posprev = pos->prev;posprev->next = posnext;posnext->prev = posprev;free(pos);
}

?3.2.12雙向鏈表銷毀

// 雙向鏈表銷毀
void LTNodeDestory(LTNode* plist)
{//防止鏈表不存在assert(plist);LTNode* cur = plist->next;while (cur != plist){LTNode* next = cur->next;free(cur);cur = next;}free(plist);plist = NULL;
}

以上代碼為單鏈表所實現的所有功能(接口)


頭文件:

#pragma once
#include<stdio.h>
#include<stdlib.h>
#include<assert.h>typedef int DataType;typedef struct ListNode
{DataType val;struct LTNode* next;struct LTNode* prev;
}LTNode;//生成新節點
LTNode* Createnode(DataType x);//哨兵位初始化
LTNode* LTInit();//帶頭雙向循環鏈表打印
void LTPrint(LTNode* plist);// 雙向鏈表銷毀
void LTNodeDestory(LTNode* plist);// 雙向鏈表尾插
void LTNodePushBack(LTNode* plist, DataType x);// 雙向鏈表尾刪
void LTNodePopBack(LTNode* plist);// 雙向鏈表頭插
void LTNodePushFront(LTNode* plist, DataType x);// 雙向鏈表頭刪
void LTNodePopFront(LTNode* plist);// 雙向鏈表查找
LTNode* LTNodeFind(LTNode* plist, DataType x);// 雙向鏈表在pos的前面進行插入
void LTNodeInsert(LTNode* pos, DataType x);// 雙向鏈表刪除pos位置的結點
void LTNodeErase(LTNode* pos);

測試文件:

#define  _CRT_SECURE_NO_WARNINGS 1
#include"list.h"
// 初步測試
void test1()
{// 創建一個哨兵位頭節點LTNode* plist = LTInit();LTPrint(plist);
}// 尾插尾刪測試
void test2()
{LTNode* plist = LTInit();LTNodePushBack(plist, 1);LTNodePushBack(plist, 2);LTNodePushBack(plist, 3);LTNodePushBack(plist, 4);LTNodePushBack(plist, 5);LTPrint(plist);LTNodePopBack(plist);LTPrint(plist);
}
// 頭插頭刪測試
void test3()
{LTNode* plist = LTInit();LTNodePushFront(plist, 1);LTNodePushFront(plist, 2);LTNodePushFront(plist, 3);LTNodePushFront(plist, 4);LTNodePushFront(plist, 5);LTPrint(plist);LTNodePopFront(plist);LTPrint(plist);
}
// 鏈表查找測試
void test4()
{LTNode* plist = LTInit();LTNodePushBack(plist, 1);LTNodePushBack(plist, 2);LTNodePushBack(plist, 3);LTNodePushBack(plist, 4);LTNodePushBack(plist, 5);LTPrint(plist);LTNode* pos = LTNodeFind(plist, 3);printf("%d\n", pos->val);}
// 雙向鏈表在pos的前面進行插入測試
void test5()
{LTNode* plist = LTInit();LTNodePushBack(plist, 1);LTNodePushBack(plist, 2);LTNodePushBack(plist, 3);LTNodePushBack(plist, 4);LTNodePushBack(plist, 5);LTPrint(plist);LTNode* pos = LTNodeFind(plist, 3);LTNodeInsert(pos, 100);LTNodeInsert(pos, 200);LTPrint(plist);}
// 雙向鏈表刪除pos位置的結點測試
void test6()
{LTNode* plist = LTInit();LTNodePushBack(plist, 1);LTNodePushBack(plist, 2);LTNodePushBack(plist, 3);LTNodePushBack(plist, 4);LTNodePushBack(plist, 5);LTPrint(plist);LTNode* pos = LTNodeFind(plist, 3);LTNodeErase(pos);LTPrint(plist);
}
// 鏈表銷毀測試
void test7()
{LTNode* plist = LTInit();LTNodePushBack(plist, 1);LTNodePushBack(plist, 2);LTNodePushBack(plist, 3);LTNodePushBack(plist, 4);LTNodePushBack(plist, 5);LTNodeDestory(plist);plist = NULL;LTPrint(plist);
}
int main()
{// 初步測試test1();// 尾插尾刪測試test2();// 頭插頭刪測試test3();// 鏈表查找測試test4();// 雙向鏈表在pos的前面進行插入測試test5();// 雙向鏈表刪除pos位置的結點測試test6();// 鏈表銷毀測試//test7();return 0;
}

四.鏈表總結

這是一個我個人做的思維導圖,對于學習鏈表的一些總結,希望對你有所幫助:

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

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

相關文章

kmalloc

kmalloc(size(結構體)*n)就是申請n個大小為結構體的空間&#xff0c;然后返回一個指向這個空間的首地址的指針。這個指針可以看作是一個數組&#xff0c;它的每個元素都是結構體&#xff0c;所以可以使用索引來訪問這個空間的不同部分。例如&#xff0c;如果你有一個指針p&…

python數據類型之字符串、字典、元組

一、數字類型 1、number類型 Python Number 數據類型用于存儲數值。 數據類型是不允許改變的,這就意味著如果改變 Number 數據類型的值&#xff0c;將重新分配內存空間。 以下實例在變量賦值時 Number 對象將被創建&#xff1a; var1 1 var2 10也可以使用del語句刪除一些…

亞馬遜防關聯要注意什么?看這一篇,防關聯有技巧!

亞馬遜賬號關聯的問題&#xff0c;對于跨境電商來說都不陌生&#xff0c;店鋪的安全問題往往和賬號關聯有關&#xff0c;一旦亞馬遜賬號被關聯就很可能導致我們的店鋪被封&#xff0c;對于被亞馬遜封店的賣家都會有申訴機會&#xff0c;如果無法成功申訴&#xff0c;那將永久被…

C語言——利用函數遞歸,編寫函數不允許創建臨時變量,求字符串長度

#define _CRT_SECURE_NO_WARNINGS 1#include<stdio.h>int my_strlen(char* str) {if(*str ! \0)return 1my_strlen(str1);elsereturn 0; }int main() {char arr[] "hello";int len my_strlen(arr); //arr是數組&#xff0c;數組傳參&#xff0c;傳過去的是第…

NB水表能承受最大的水壓是多少?

NB水表&#xff0c;作為新一代智能水表&#xff0c;以小巧的體積、穩定的性能和強大的功能贏得了市場的認可。那么&#xff0c;它究竟能承受多大的水壓呢&#xff1f;接下來&#xff0c;小編來為大家揭秘下&#xff0c;一起來看下吧&#xff01; 一、NB水表概述 NB水表&#xf…

安卓手機好用的清單軟件有哪些?

生活中每個人都有丟三落四的習慣&#xff0c;伴隨著生活節奏的加快&#xff0c;人們常忘事的情況會更加頻繁的出現&#xff0c;這時候很多人就開始選擇手機上記錄清單類的軟件&#xff0c;安卓手機在手機市場中占有很大的分量&#xff0c;在安卓手機上好用的記錄清單的軟件有哪…

在高斯DB數據庫中,獲取上個月的日期

個人網站 返回上個月的日期。ADD_MONTHS函數用于對日期進行加減操作&#xff0c;通過將當前日期減去1個月來獲取上個月的日期。請注意&#xff0c;這里使用的是負數來表示減去一個月的時間間隔。 SELECT ADD_MONTHS(CURRENT_DATE, -1) AS last_month;

SiP封裝、合封芯片和芯片合封是一種技術嗎?都是合封芯片技術?

合封芯片、芯片合封和SiP系統級封裝經常被提及的概念。但它們是三種不同的技術&#xff0c;還是同一種技術的不同稱呼&#xff1f;本文將幫助我們更好地理解它們的差異。 一、合封芯片與SiP系統級封裝的定義 首先合封芯片和芯片合封都是一個意思 合封芯片是一種將多個芯片&a…

力扣labuladong——一刷day49

提示&#xff1a;文章寫完后&#xff0c;目錄可以自動生成&#xff0c;如何生成可參考右邊的幫助文檔 文章目錄 前言一、力扣513. 找樹左下角的值二、力扣666. 路徑總和 IV三、力扣1261. 在受污染的二叉樹中查找元素四、力扣572. 另一棵樹的子樹 前言 二叉樹的遞歸分為「遍歷」…

【Leetcode每日一題】mid——6. N 字形變換

題目描述 https://leetcode.cn/problems/zigzag-conversion/description/ 將一個給定字符串 s 根據給定的行數 numRows &#xff0c;以從上往下、從左到右進行 Z 字形排列。 比如輸入字符串為 “PAYPALISHIRING” 行數為 3 時&#xff0c;排列如下&#xff1a; 之后&#xff0…

技術細分|推薦系統——推薦系統中的數據去偏方法

本篇的主要脈絡同樣依據中科大何向南教授、合工大汪萌教授聯合在 TKDE 上的一篇綜述文章展開&#xff1a;Bias and Debias in Recommender System: A Survey and Future Directions。 下面按照前導文章中介紹的數據偏差 Selection Bias、Conformity Bias、Exposure Bias、Posit…

PDF添加文字或者圖片

引入依賴 <dependency><groupId>org.apache.pdfbox</groupId><artifactId>fontbox</artifactId><version>2.0.4</version> </dependency> <dependency><groupId>org.apache.pdfbox</groupId><artifactI…

找JPG格式圖片的地址(持續更新中)

問題描述&#xff1a;找JPG格式圖片的地址 解決辦法&#xff1a; 第一個 谷歌的images 第二個&#xff0c;搜狗圖片和百度圖片 不過下載是WEBP格式&#xff0c;可以使用一個在線WEBP格式轉JPG格式的在線網站即可。 轉換的網址為&#xff1a; https://ezgif.com/webp-to-j…

【學歷是敲門磚】如果你想有個好的起點,不妨沖一沖計算機考研,這本書將會助你一臂之力

目錄 計算機考研難點 《計算機考研精煉1000題》揭秘問答 1. 為什么是1000題&#xff1f; 2. 有什么優勢&#xff1f; 3. 編寫團隊水平如何&#xff1f; 4. 題目及解析品質如何&#xff1f;可以試讀嗎&#xff1f; 購買鏈接 高質量的學習提升圈子 京東熱賣下單鏈接&…

可視化NGINX管理平臺Nginx Proxy Manager

# for CentOSyum install docker-compose -y# for Ubuntuapt-get install docker-compose -y 如果提示&#xff1a; 沒有可用軟件包 docker-compose&#xff0c; 錯誤&#xff1a;無須任何處理 通過 pip 安裝 docker-compose # 添加企業版附加包 yum -y install epel-rel…

java--static的注意事項

1.使用類方法、實例方法時的幾點注意事項 ①類方法中可以直接訪問類的成員&#xff0c;不可以直接訪問實例成員。 ②實例方法中既可以直接訪問類成員&#xff0c;也可以直接訪問實例成員。 ③實例方法中可以出現this關鍵字&#xff0c;類方法中不可以出現this關鍵字的。

利用工業網關進行設備數采的方法-天拓四方分享

在工業物聯網&#xff08;IIoT&#xff09;中&#xff0c;設備數采是一種關鍵技術&#xff0c;它通過收集、分析和傳輸設備運行過程中的各種數據&#xff0c;為工業制造提供重要的信息和洞察。隨著工業4.0和智能制造的快速發展&#xff0c;工業數據采集和處理已經成為工業物聯網…

甲方使用外包真的能節約成本嗎?

語&#xff1a;外包作為一種常見的業務模式&#xff0c;被廣泛應用于各行各業。然而&#xff0c;甲方在選擇外包時&#xff0c;是否真的能夠實現成本節約呢&#xff1f;本文將從多個角度進行探討。 正文&#xff1a; 降低人力成本&#xff1a;外包通常是將某些業務環節或項目交…

2022年全國英烈紀念設施數據,各區縣均有!

中國是一個擁有悠久歷史和燦爛文化的國家&#xff0c;其英烈紀念設施承載著中國人民對為國家獨立、民族解放和民主進步而英勇斗爭的先烈們的崇敬和緬懷之情。 這些設施不僅是中國革命歷史和先烈精神的重要載體&#xff0c;也是傳承紅色文化、弘揚革命精神的重要場所。 今天分享…

【RtpRtcp】3: webrtc m79:video 相關創建及切片、發送

m79 的 客戶端代碼流程。 對于視頻幀: CreateRtpStreamSenders 管理一組RtpStreamSender ,每一個RtpStreamSender 都進行rtp包的發送: 具體發送是RTPSenderVideo 處理,RTPSenderVideo 對收到的h264 幀,進行幀分片rtp,然后一組包一起使用LogAndSendToNetwork 發送的。 Rtp…