移除鏈表元素+反轉鏈表+鏈表的中間節點+合并兩個有序鏈表+環形鏈表約瑟夫問題+分割鏈表

一、移除鏈表元素

給你一個鏈表的頭節點 phead?和一個整數 val?,請你刪除鏈表中所有滿足 Node.val == val?的節點,并返回?新的頭節點?

(列表中的節點數目在范圍?[0, 104]?內)

示例:輸入:head = [1,2,6,3,4,5,6], val = 6? ? ? ? ??輸出:[1,2,3,4,5]

? ? ? ? ? 輸入:head = [ ], val = 1? ? ? ? ? ? ? ? ? ? ? ? ? ? ??輸出:[ ]?

? ? ? ? ? 輸入:head = [7,7,7,7], val = 7? ? ? ? ? ? ? ? ? ??輸出:[ ]

思路1:創建一個新鏈表,遍歷找值不為val的節點,尾插到新的鏈表中

需要創建一個指針pcur,讓它從phead開始尋找不為val的節點,將它們尾插在新的鏈表中,至于等于val的節點就跳過它;除此之外,我們還需要創建一個新鏈表,用兩個指針newHead,newTail來保存新的頭節點和尾節點,開始時先將它們置為NULL。

但是需要注意:根據題目給的鏈表內節點數目的范圍,可知鏈表有為空的情況,需要判空,如果原鏈表為空,意味著原鏈表內沒有任何節點,那么就不需要再進行遍歷循環,直接跳出了函數,返回一個空的新鏈表

//移除鏈表元素函數
SLNode* removeElements(SLNode* phead,int val)
{//創建新鏈表SLNode* newHead = NULL;SLNode* newTail = NULL;//遍歷原鏈表SLNode* pcur = phead;while(pcur){//找到不為val的節點,尾插到新鏈表中if(pcur->val != val){//鏈表為空if(newHead == NULL){newHead = newTail = pcur;}else{//鏈表不為空newTail->next = pcur;newTail = newTail->next;}}pcur = pcur->next;}if(newTail) //當原鏈表為空時,不需要進行置空操作newTail->next = NULL;//返回新的頭節點return newHead;
}
//創建單鏈表節點結構
typedef struct SListNode
{int val;struct SListNode* next;
}SLNode;
//創建新節點
SLNode* newnode(int x)
{SLNode* node = (SLNode*)malloc(sizeof(SLNode));if(node == NULL){perror("malloc");exit(1);}node->val = x;node->next = NULL;return node;
}
//打印鏈表
void Print(SLNode* phead)
{SLNode* pcur = phead;while(pcur){printf("%d ",pcur->val);pcur = pcur->next;}printf("\n");
}
int main()
{//創建測試鏈表:1->2->6->3->4->5->6SLNode* phead = newnode(1);phead->next = newnode(2);phead->next->next = newnode(6);phead->next->next->next = newnode(3);phead->next->next->next->next = newnode(4);phead->next->next->next->next->next = newnode(5);phead->next->next->next->next->next->next = newnode(6);printf("原始鏈表:");Print(phead);int val = 6;SLNode* result = removeElements(phead,val);printf("移除%d后的新鏈表:",val);Print(result);//釋放鏈表內存while(result){SLNode* tmp = result;result = result->next;free(tmp);tmp = NULL;}return 0;
}

測試原鏈表為空時:

SLNode* phead = NULL;

測試原鏈表元素相同時:

SLNode* phead = newnode(7);
phead->next = newnode(7);
phead->next->next = newnode(7);
phead->next->next->next = newnode(7);int val = 7;

思路2:遍歷原鏈表,將值為val的節點釋放

使用 prev,pcur,next三指針法:pcur表示當前的節點,prev表示當前節點的前一個節點,next表示當前節點的下一個節點;將pcur節點釋放掉之前,需要改變prev的next節點變為next,才能將其釋放掉,初始時將prev和next置為NULL

SLNode* removeElements(SLNode* phead,int val)
{SLNode* prev = NULL;//前一個節點指針SLNode* pcur = phead;//當前節點指針SLNode* next = NULL;//下一個節點指針while(pcur){next = pcur->next;//保存下一個節點if(pcur->val == val){//刪除當前節點if(prev == NULL){//刪除的是頭節點phead = next;//更新頭指針}else{//刪除的是中間或尾節點prev->next = next;//釋放當前節點內存free(pcur);pcur = NULL;}}else{//當前節點保留,更新prev指針prev = pcur;}//移動到下一個節點pcur = next;}return phead;
}

二、反轉鏈表

給你單鏈表的頭節點 phead?,請你反轉鏈表,并返回反轉后的鏈表。

(鏈表中節點的數目范是?[0, 5000])

示例:?輸入:head = [1,2,3,4,5]? ? ??輸出:[5,4,3,2,1]

? ? ? ? ? ? 輸入:head = [1,2]? ? ? ? ? ? ? ?輸出:[2,1]

? ? ? ? ? ? 輸入:head = [ ]? ? ? ? ? ? ? ? ? ??輸出:[ ]

思路1:創建新鏈表,將原鏈表中的節點拿過來頭插

用兩個指針newHead,newTail來保存新鏈表的頭節點和尾節點,每頭插一個節點newHead就跟著變化,變成新的頭節點

根據題目節點的數目范圍可知,鏈表有可能為空鏈表,因此需要判空。

SLNode* reverseList(SLNode* phead)
{//創建一個空鏈表SLNode* newHead = NULL;SLNode* newnode = NULL;//遍歷原鏈表SLNode* pcur = phead;while(pcur){//1.保存下一個節點(防止丟失)SLNode* next = pcur->next;if(newHead == NULL){newHead = newTail = pcur;pcur->next = NULL;}else{//2.將當前節點插入新鏈表頭部pcur->next = newHead;//當前節點指向新鏈表的第一個節點newHead = pcur;//更新新鏈表頭指針}//3.移動到原鏈表的下一個節點pcur = next;}return newHead; //如果元鏈表為空,直接會返回NULL
}

如果新鏈表只給一個指針newHead來維護:

SLNode* reverseList(ListNode* phead)
{//創建新鏈表SLNode* newHead = NULL;//遍歷鏈表SLNode* pcur = phead;    while(pcur){//1.保存下一個節點(防止丟失)SLNode* next = pcur->next;//2.將當前節點插入新鏈表頭部pcur->next = newHead;newHead = pcur;//3.移動到原鏈表的下一個節點pcur = next;}return newHead;
}

思路2:創建三個指針,完成原鏈表的反轉

創建三個指針n1,n2,n3,分別表示當前節點的前一個節點,當前節點,當前節點的后一個節點,開始時n1置為NULL。具體做法:(1)讓n2的next指針指向n1

? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? (2)然后n1=n2; n2=n3; n3=n3->next

SLNode* reverseList(ListNode* phead)
{//判空if(phead == NULL){return NULL;}//創建三個指針SLNode* n1,n2,n3;n1 = NULL,n2 = phead, n3 = n2->next;while(n2){n2->next = n1;n1 = n2;n2 = n3;if(n3)n3 = n3->next;}//指向新的頭節點n1return n1;
}

三、鏈表的中間節點

給你單鏈表的頭結點?phead?,請你找出并返回鏈表的中間結點。

如果有兩個中間結點,則返回第二個中間結點。

(鏈表的結點數范圍是?[1, 100]

示例:輸入:head = [1,2,3,4,5]? ??輸出:[3,4,5] 鏈表只有一個中間結點,值為 3

輸入:head = [1,2,3,4,5,6]??輸出:[4,5,6] 該鏈表有兩個中間結點,值分別為 3 和 4 ,返回第二個結點

思路1:遍歷原鏈表,使用count變量計數,直接返回 count/2 節點

例如,當有奇數個節點時,5個節點,則 5/2=2,2即中間節點

? ? ? ? ? ?當有偶數個節點時,6個節點,則 6/2=3,3即中間節點

SLNode* middleNode(SLNode* phead)
{if(phead == NULL){return NULL; //空鏈表直接返回}//第一次遍歷:計算鏈表長度int count = 0;SLNode* pcur =phead;while(pcur){count++;pcur = pcur->next;}//計算中間位置int mid = count/2;//第二次遍歷:移動到中間節點pcur = phead;if(int i = 0;i < mid; i++){pcur = pcur->next;}return pcur;
}

測試奇數個節點時:

測試偶數個節點時:

測試只有一個節點和空鏈表時:

思路2:快慢指針

slow每次走一步,fast每次走兩步,

例如,當有奇數個節點時,5個節點,slow走一步,fast走兩步,到最后一個節點時,fast->next 剛好等于NULL(fast->next == NULL),slow指向的剛好是中間節點;

當有偶數個節點時,6個節點,slow走一步,fast走兩步,到最后一個節點時,fast剛好等于NULL(fast == NULL),slow指向的剛好是中間節點

SLNode* middleNode(SLNode* phead)
{if(phead == NULL){return NULL;}//創建快慢指針SLNode* slow = phead;SLNode* fast = phead;//快指針每次移動兩步,慢指針每次移動一步while(fast && fast->next) //不可以反過來寫成 (fast->next && fast),因為如果鏈表中有偶數個節點的情況下,fast最后一次會直接走空 NULL,{                         //fast->next執行會報錯slow = slow->next;    fast = fast->next->next;}//此時slow剛好指向的就是中間節點return slow;
}

四、合并兩個有序鏈表

將兩個升序鏈表合并為一個新的?升序?鏈表并返回。新鏈表是通過拼接給定的兩個鏈表的所有節點組成的。

(兩個鏈表的節點數目范圍是?[0, 50],

?l1?和?l2?均按?非遞減順序?排列)

示例:輸入:l1 = [1,2,4] , l2 = [1,3,4]? ? ? ?輸出:[1,1,2,3,4,4]

? ? ? ? ? ?輸入:l1 = [ ], l2 = [ ]? ? ? ? ? ? ? ? ? ? ??輸出:[ ]

? ? ? ? ? ?輸入:l1 = [ ] , l2 = [0]? ? ? ? ? ? ? ? ? ? ?輸出:[0]

思路:創建一個空鏈表,遍歷原鏈表,將節點值小的節點拿到新的鏈表中進行尾插操作

需要創建兩個指針l1,l2,分別遍歷兩個原鏈表,還要創建一個新的鏈表,同時維護新鏈表的頭指針(newHead)和尾指針(newTail)

和前面我們做的順序表的 合并兩個有序數組 算法題一樣,結果只有兩種情況:要么l1為空,要么l2為空

SLNode* mergeTwoLists(SLNode* list1,SLNode* list2)
{//判空if(list1 == NULL){return list2;//如果兩個鏈表都為空,則會返回空鏈表[ ]}if(list2){return list1;}SLNode* l1 = list1;SLNode* l1 = list2;//創建新鏈表SLNode* newHead,newTail;newHead = newTail = NULL;while(l1 && l2){if(l1->val < l2->val){//l1拿下來尾插if(newHead == NULL){newHead = newTail = l1;}else{newTail->next = l1;newTail = newTail->next;}l1 = l1->next;}else{//l2拿下來尾插if(newHead == NULL){newHead = newTail = l2;}else{newTail->next = l2;newTail = newTail->next;}l2 = l2->next;}}//跳出循環有兩種情況:要么l1走到空,要么l2走到空if(l1){newTail->next = l1;}if(l2){newTail->next = l2;}return newHead;
}

測試空鏈表時:

測試有一個鏈表為空一個不為空時:

添加哨兵位節點優化代碼

在上面的代碼中,存在重復的代碼(如下圖所示),如何優化?

重復的原因:新鏈表存在空鏈表和非空鏈表兩種情況,解決思路:讓新鏈表不為空--頭尾指針都指向一個有效的地址(節點),即使用帶頭鏈表(哨兵位節點)

將較小的節點一個個尾插到新鏈表的哨兵節點后面,遍歷完成之后返回的是鏈表的第一個有效節點

(哨兵節點詳情:數據結構-單鏈表-CSDN博客)

SLNode* mergeTwoLists(ListNode* list1, ListNode* list2)
{//判空if (list1 == NULL){return list2;// [ ]如果兩個鏈表都為空,則會返回空鏈表}if (list2 == NULL){return list1;}SLNode* l1 = list1;SLNode* l2 = list2;//創建新的鏈表SLNode* newHead,*newTail;//創建哨兵節點newHead = newTail = (SLNode*)malloc(sizeof(SLNode));while(l1 && l2){if(l1->val <l2->val){newTail->next = l1;newTail = newTail->next;l1 = l1->next;}else{newTail->next = l2;newTail = newTail->next;l2 = l2->next;}}if(l1){newTail->next = l1;}if(l2){newTail->next = l2;}//動態申請的空間手動釋放掉SLNode* ret = newHead->next; //返回的是第一個有效節點free(newHead);newHead = NULL;return ret;
}

五、循環鏈表經典應用-環形鏈表的約瑟夫問題

【背景:著名的Josephus問題

據說著名猶太歷史學家 Josephus有過以下的故事:在羅馬人占領喬塔帕特后,39個猶太人與 Josephus及他的朋友躲到?個洞中,39個猶太人決定寧愿死也不要被?抓到,于是決定了?個自殺方式,41個?排成?個圓圈,由第1個?開始報數,每報數到第3?該?就必須自殺,然后再由下? 個重新報數,直到所有?都自殺身亡為止。 然?Josephus和他的朋友并不想遵從,Josephus要他的朋友先假裝遵從,他將朋友與自己安排在 第16個與第31個位置,于是逃過了這場死亡游戲。】

題目:編號為 1?到 n?的 n?個人圍成一圈。從編號為 1?的人開始報數,報到 m?的人離開。

下一個人繼續從 1?開始報數。

n-1 輪結束以后,只剩下一個人,問最后留下的這個人編號是多少?

示例:輸入:5,2? ? ? ? ? 輸出:3

說明:

開始5個人 1,2,3,4,5 ,從1開始報數,1->1,2->2編號為2的人離開

1,3,4,5,從3開始報數,3->1,4->2編號為4的人離開

1,3,5,從5開始報數,5->1,1->2編號為1的人離開

3,5,從3開始報數,3->1,5->2編號為5的人離開

最后留下人的編號是3

思路:第一步:創建帶環鏈表 第二步:計數

我們通過題意可知,是一個環形的,循環的鏈表,依然可以用雙指針法解決,創建兩個指針pcur,prev,pcur代表當前鏈表的節點,prev表示該節點的前一個節點,根據示例,一共有5個人,報數報到2的人要離開;prev開始的位置是在最后一個人即5的位置,pcur開始的位置就是1,走到下一步的時候就是2,是需要刪除(離開)的節點,刪除方式:pcur走到2時,此時的prev也要跟著走一步,到1的位置,改變prev的next指針的指向位置,即由 prev->next=pcur變成prev->next=pcur->next,然后就可以刪除pcur位置的節點;接著,此時pcur由刪除的節點位置繼續往下走,走向下一個有效的節點繼續從1開始報數,然后重復上述的操作

SLNode* creatCircle(int n)
{//先創建第一個節點SLNode* phead = newnode(1);SLNpde* ptail = phead;for(int i = 0;i <= n; i++){ptail->next = newnode(i);ptail = ptail->next;}//首尾相連,鏈表成環ptail->next = phead;return ptail;
}
int ysf(int n,int m)
{//1.根據n創建帶環鏈表SLNode* prev = creatCircle(n);SLNode* pcur = prev->next;int count = 1;//當鏈表中只有一個節點的情況 pcur->next == pcur,這個節點的數據就是留到最后的人while(pcur->next != pcur){if(count == m){//銷毀pcur節點prev->next = pcur->next;free(pcur);pcur = prev->next;count = 1;}else{//此時不需要銷毀節點prev = pcur;pcur = pcur->next;count++;}}//此時剩下的一個節點就是要返回的節點里的值int ret = pcur->val;free(pcur);pcur = NULL:return ret;
}

六、分割鏈表

給你一個鏈表的頭節點?phead?和一個特定值?x?,請你對鏈表進行分隔,使得所有?小于?x?的節點都出現在?大于或等于?x?的節點之前。

你不需要?保留?每個分區中各節點的初始相對位置。

(鏈表中節點的數目在范圍?[0, 200]?內)

示例:輸入:head = [1,4,3,2,5,2], x = 3? ? ? ? ??輸出:[1,2,2,4,3,5]

? ? ? ? ? ?輸入:head = [2,1], x = 2? ? ? ? ? ? ? ? ? ? ? 輸出:[1,2]

思路1:創建兩個新鏈表--小鏈表和大鏈表

將原鏈表中小于x的pcur節點的值尾插到小鏈表中,同時維護小鏈表的頭指針(lessHead)和尾指針(lessTail)

將原鏈表中大于或等于x的pcur節點的值尾插到大鏈表中,同時維護大鏈表的頭指針(greaterHead)和尾指針(greaterTail),最后將小鏈表的尾節點與大鏈表的第一個有效節點首尾相連

SLNode* partition(SLNode* phead,int x)
{//判空if(phead == NULL){return phead;}//創建兩個帶頭鏈表SLNode* lessHead,*lessTail;SLNode* greaterHead,*greaterTail;lessHead = lessTail = (SLNode*)malloc(sizeof(SLNode));greaterHead = greaterTail = (SLNode*)malloc(sizeof(SLNode));//遍歷原鏈表,將原鏈表中的節點尾插到大小鏈表中SLNode* pcur = phead;while(pcur){if(pcur->val < x){//尾插到小鏈表中lessTail->next = pcur;lessTail = lessTail->next;}else{//尾插到大鏈表中greaterTail->next = pcur;greaterTail = greaterTail->next;}pcur = pcur->next;}//修改大鏈表的尾節點的next指針指向(終止大鏈表)greaterTail->next = NULL;//若不加這一行,代碼會出現死循環+next指針初始化//小鏈表的尾節點和大鏈表的第一個有效節點首尾相連lessTail->next = greaterHead->next;//釋放SLNode* ret = lessHead->next;free(lessHead);free(greaterHead);lessHead = greaterHead = NULL;return ret;
}

測試空鏈表:

測試只有小于x或大于等于x的情況:

思路2:創建一個新鏈表

將原鏈表中若pcur節點的值小于x,頭插到新鏈表中,若pcur節點的值大于或等于x,尾插到新鏈表中,同時維護新鏈表的頭指針(newHead)和尾指針(newTail),給新鏈表一個哨兵節點

SLNode* partition(SLNode* phead,int x)
{if(phead == NULL){return NULL;}//創建一個帶頭鏈表//創建哨兵節點作為新鏈表的頭SLNode* newHead,*newTail;newHead = newTail = (SLNode*)malloc(sizeof(SLNode));newHead->next = NULL;    SLNode* pcur = phead;while(pcur){//保存下一個節點SLNode* next = pcur->next;//在頭插操作時,pcur 的 next 會被修改if(pcur->val < x){//頭插到哨兵節點后面//要在哨兵節點newHead后面進行頭插,即在newHead->next節點位置開始進行頭插,而這個位置原本為NULL,即newHead,newHead->next=NULL=NULL//現在要變成 newHead,pcur,newHead->next=NULL,在NULL前面插入pcur,那么pcur->next就變成了NULL(pcur->next = newHead->next;)//哨兵節點的next節點就變成了pcur(newHead->next = pcur; )pcur->next = newHead->next;newHead->next = pcur;//如果是第一個節點,需要更新newTailif(newTail == newHead){newTail = pcur;}}else{//尾插到鏈表末尾newTail->next = pcur;newTail = pcur;//newTail = newTail->next 更新尾指針 }pcur = next;}newTail->next = NULL;// 確保鏈表終止//釋放SLNode* ret = newHead->next;free(newHead);newHead = NULL;return ret;
}

思路3:遍歷原鏈表,在原鏈表上進行修改

若pcur節點的值小于x,往后走,若pcur節點的值大于或等于x,尾插到原鏈表后,刪除舊節點

我們需要一個指針pcur,表示當前的節點,prev指針則表示當前節點的前一個節點(設置prev開始時的位置在哨兵節點上),pcur每走一步,prev就保存pcur前一步的位置,還需要一個ptail指針表示原鏈表的尾節點(ptail一直保持位置不變,表示原尾節點位置),一個newTail指針表示隨著每次尾插的變化的新的尾節點

當走到大于或等于x的節點位置時,修改prev的next指針的位置,即prev->next=pcur變成prev->next=pcur->next,然后將pcur節點尾插到原鏈表后面,newTail跟著移動,將舊的pcur節點刪除掉,再接著繼續往后走,重復以上的操作。

SLNode* partition(SLTNode* phead, int x)
{if(phead == NULL || phead->next == NULL) //鏈表為空或鏈表只有一個節點{return phead;}//1.找到原鏈表的尾節點SLNode* ptail = phead;while(ptail->next){ptail = ptail->next;}SLNode* newTail = ptail;//新的尾節點指針    //2.創建哨兵節點簡化操作SLNode* newHead = (SLNode*)malloc(sizeof(SLNode));newHead->next = phead;SLNode* prev = newHead;//前驅指針SLNode* pcur = phead;//當前指針//3.遍歷鏈表直到原始尾節點while(pcur != ptail){if(pcur->val < x){//保留當前節點,繼續前進prev = pcur;pcur = pcur->next;}else{//將當前節點移到鏈表末尾//從原位置移除當前節點prev->next = pcur->next;//將當前節點插入到末尾newTail->next = pcur;pcur->next = NULL;newTail = pcur;//更新新的尾節點//移動pcur到prev的下一個節點pcur = prev->next;//相當于pcur=pcur->next,但是不能這么寫,因為此時pcur->next 已經被設為 NULL,會導致錯誤}}//4.處理原始尾節點if(ptail->val >= x && ptail != newTail)//如果ptail已經是newTail(即已經被移動過一次),這個條件ptail != newTail可以防止重復移動{//如果原始尾節點需要移動prev->next = ptail->next;//實際上ptail->next是NULL,因為ptail是原始鏈表的尾節點,它的next本來就是NULLnewTail->next = ptail;ptail->next = NULL;newTail = ptail;}//5.釋放哨兵節點并返回結果SLNode* ret = newHead->next;free(newHead);newHead = NULL;return ret;
}

其實不用處理尾節點也可以,因為到了尾節點的部分要么前面的節點包括尾節點本身都是小于x的,不用移動保持原樣,要么尾節點是大于等于x的,就尾插到當前鏈表的末尾

關鍵說明:為什么可以不需要單獨處理尾節點

  1. 當原始尾節點小于 x 時

    • 當?pcur?指向原始尾節點時,進入 if 分支

    • 執行?prev = pcur?和?pcur = pcur->next

    • 由于原始尾節點的?next?是?NULLpcur?變為?NULL

    • 循環條件?while(pcur != NULL)?不滿足,循環結束

  2. 當原始尾節點大于等于 x 時

    • 當?pcur?指向原始尾節點時,進入 else 分支

    • 執行?prev->next = pcur->next(設置為?NULL

    • 執行?newTail->next = pcur(將節點移到末尾)

    • 執行?pcur->next = NULL?和?newTail = pcur

    • 執行?pcur = prev->next(變為?NULL

    • 循環條件?while(pcur != NULL)?不滿足,循環結束

SLNode* partition(SLNode* phead, int x)
{if(phead || phead->next){return phead;}SLNode* ptail = phead;while(ptail->next){ptail = ptail->next;}SLNode* newTail = ptail;SLNode* newHead = (SLNode*)malloc(sizeof(SLNode));newHead->next = phead;SLNode* prev = newHead;SLNode* pcur = phead;while(pcur){if(pcur->val > x){prev = pcur;pcur = pcur->next;}else{prev->next = pcur->next;newTail->next = pcur;pcur->next = NULL;newTail = pcur;pcur = prev->next;}}SLNode* ret = newHead->next;free(newHead);newHead = NULL;return ret;
}

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

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

相關文章

vue3+arcgisAPI4示例:軌跡點模擬移動(附源碼下載)

demo源碼運行環境以及配置運行環境&#xff1a;依賴Node安裝環境&#xff0c;需要安裝Node。 運行工具&#xff1a;vscode或者其他工具。 配置方式&#xff1a;下載demo源碼&#xff0c;vscode打開&#xff0c;然后順序執行以下命令&#xff1a; &#xff08;1&#xff09;下載…

Design Compiler:Milkyway庫的創建與使用

相關閱讀 Design Compilerhttps://blog.csdn.net/weixin_45791458/category_12738116.html?spm1001.2014.3001.5482 DC Ultra推出了拓撲模式&#xff0c;在綜合時會對標準單元進行粗布局(Coarse Placement)并使用虛擬布線(Virtual Routing)技術計算互聯延遲&#xff0c;關于拓…

嵌入式教學的云端革命:高精度仿真如何重塑倒車雷達實驗與工程教育——深圳航天科技創新研究院賦能新一代虛實融合實訓平臺

一、嵌入式教學的困境與破局之道 在傳統嵌入式系統教學中&#xff0c;硬件依賴始終是核心痛點。以“倒車雷達實驗”為例&#xff0c;學生需操作STM32開發板、超聲波傳感器、蜂鳴器等硬件&#xff0c;面臨設備損耗、接線錯誤、調試效率低等問題。更關鍵的是&#xff0c;物理硬件…

flutter-boilerplate-project 學習筆記

項目地址&#xff1a; https://github.com/zubairehman/flutter_boilerplate_project/tree/master 樣板包含創建新庫或項目所需的最小實現。存儲庫代碼預加載了一些基本組件&#xff0c;例如基本應用程序架構、應用程序主題、常量和創建新項目所需的依賴項。通過使用樣板代碼…

集成電路學習:什么是CMSIS微控制器軟件接口標準

CMSIS,即Cortex Microcontroller Software Interface Standard(Cortex微控制器軟件接口標準),是由ARM公司與多家不同的芯片和軟件供應商緊密合作定義的一個標準。該標準旨在為基于ARM Cortex處理器的微控制器提供一套與供應商無關的硬件抽象層,從而簡化軟件的開發、重用,…

由淺入深使用LangGraph創建一個Agent工作流

創建一個簡單的工作流&#xff1a;Start ——> 節點1(固定輸入輸出) ——> Endfrom langchain_core.messages import SystemMessage, HumanMessage, AIMessage from langgraph.graph import StateGraph, START, END from typing_extensions import TypedDict from typing…

PL-0功能拓展及基于VSCode的IDE配置

title: PL/0功能拓展及基于VSCode的IDE配置 date: 2024-08-06 22:46:38 tags: 做過的實驗||項目復盤 top: true 概述PL/0語言可以看成PASCAL語言的子集,它的編譯程序是由C語言編寫的編譯解釋執行系統。PL/0能充分展示高級語言的最基本成分。拓展了pl0語言的基礎功能&#xff08…

【低空經濟】大型露天礦區安全生產無人機巡查與管理系統設計

1. 引言 大型露天礦區因其廣闊的作業區域和復雜的環境條件&#xff0c;安全生產管理面臨著嚴峻的挑戰。隨著科技的進步&#xff0c;無人機作為一種現代化的巡查工具&#xff0c;逐漸被應用于礦區的安全生產管理中。無人機具備高效、靈活、成本相對低廉等優點&#xff0c;可以在…

SpringCloud學習第一季-3

目錄 11.服務網關-Gateway新一代網關 一、Gateway概述 1、Gateway是什么 1.1 概述 2、 能干嘛 3、微服務架構中網關在哪里 4、為什么選擇gateway? 4.1 SpringCloud Gateway具有如下特性 4.2 SpringCloud Gateway 與 Zuul的區別 5、Zuul1.x模型 6、gateway模型 二、…

超越邊界:MongoDB 16MB 文檔限制的 pragmatic 解決方案

在軟件開發中&#xff0c;我們選擇的技術棧往往帶有一些固有的設計邊界。對于 MongoDB 而言&#xff0c;其最著名的邊界之一便是 BSON 文檔最大 16MB 的大小限制。在大多數場景下&#xff0c;這個限制是綽綽有余的&#xff0c;它鼓勵開發者設計更為精簡和規范的數據模型。然而&…

深入探討:PostgreSQL正則表達式中的郵政編碼匹配

引言 在處理大量數據時,如何高效地從字符串中提取特定模式的文本,如郵政編碼,是一個常見且具有挑戰性的任務。本文將通過一個具體實例,探討在PostgreSQL中使用正則表達式匹配加拿大郵政編碼的問題,并提供解決方案。 問題描述 我們希望能夠從字符串中提取所有符合加拿大…

集合框架(重點)

第十五天集合框架1.什么是集合 Collections集合Collection&#xff0c;也是一個數據容器&#xff0c;類似于數組&#xff0c;但是和數組是不一樣的。集合是一個可變的容器&#xff0c;可以隨時向集合中添加元素&#xff0c;也可以隨時從集合中刪除元素。另外&#xff0c;集合還…

深度學習核心:神經網絡-激活函數 - 原理、實現及在醫學影像領域的應用

&#x1f9d1; 博主簡介&#xff1a;CSDN博客專家、CSDN平臺優質創作者&#xff0c;高級開發工程師&#xff0c;數學專業&#xff0c;10年以上C/C, C#,Java等多種編程語言開發經驗&#xff0c;擁有高級工程師證書&#xff1b;擅長C/C、C#等開發語言&#xff0c;熟悉Java常用開發…

OneCode3.0 核心表達式技術深度剖析:從架構設計到動態擴展

一、引言&#xff1a;表達式技術在企業級框架中的核心價值 在當今快速變化的企業級應用開發中&#xff0c;動態性和靈活性已成為衡量框架優劣的關鍵指標。OneCode 3.0 框架作為企業級應用開發的重要工具&#xff0c;其核心表達式技術提供了一種強大的解決方案&#xff0c;使開發…

[css]旋轉流光效果

實現一個矩形的旋轉流光邊框效果。 需要使用css屬性梯度漸變&#xff1a;鏈接: conic-gradient&#xff0c;他指的是圓錐形變化的梯度。 // html<div class"demo"></div>// css body {width: 100%;height: 100%;background-color: black; }.demo {width…

NPM組件 @0xme5war/apicli 等竊取主機敏感信息

【高危】NPM組件 0xme5war/apicli 等竊取主機敏感信息 漏洞描述 當用戶安裝受影響版本的 0xme5war/apicli 等NPM組件包時會竊取用戶的主機名、用戶名、工作目錄、IP地址等信息并發送到攻擊者的電報地址(botToken “7699295118:AAF6pb7t718vjHWHwFQlZOastZQYHL8IVDE”&#x…

計算機網絡:組播和多播有什么區別?

在網絡通信中&#xff0c;“組播”和“多播”其實是同一概念的不同中文翻譯&#xff0c;它們對應的英文都是 Multicast。二者本質上沒有技術區別&#xff0c;只是因翻譯習慣不同而產生的兩種表述&#xff0c;在實際應用中可以通用。 不過&#xff0c;為了更清晰地理解這個概念&…

Amazon Q Developer:AI 增強編碼生產力的未來

Amazon Q Developer&#xff1a;重塑編碼體驗的 AI 助手 在如今快節奏的軟件開發世界中&#xff0c;開發者們始終在尋找能平衡生產力與探索欲的工具。而 Amazon 推出的 Amazon Q Developer&#xff0c;這款可嵌入 Visual Studio Code 等主流 IDE 的 AI 編碼助手&#xff0c;無疑…

linux eval命令的使用方法介紹

在這篇文章中&#xff0c;讓我們來詳細地介紹一下 Linux 中另一個非常強大但也極其危險的命令&#xff1a;eval。 eval 是一個 shell 內置命令&#xff0c;它的名字是 “evaluate”&#xff08;評估&#xff09;的縮寫。它的作用是將緊跟其后的參數&#xff08;一個或多個字符串…

JavaWeb筆記2-JavaScriptVueAjax

1. JavaScript 1.1 基礎介紹 JavaScript(簡稱&#xff1a;JS)是一門跨平臺、面向對象的腳本語言&#xff0c;是用來控制網頁行為&#xff0c;實現頁面的交互效果。JavaScript和Java是完全不同的語言&#xff0c;但基本語法類似組成 ECMAScript: 規定了JS基礎語法核心知識&…