1. 程式人生 > 其它 >Linux核心網路協議棧:udp資料包傳送(原始碼解讀)

Linux核心網路協議棧:udp資料包傳送(原始碼解讀)

反轉一個單鏈表。連結串列為無頭結點、單向、不迴圈。(由於涉及到結構體,所以寫不了完整的測試程式碼,下面展示的程式碼為LeetCode中寫的程式碼)

//第一次嘗試:
//本題我寫了三種解題方法
//三種方法之外的方法:動態申請能裝下連結串列資料的空間,然後將連結串列資料存放到陣列中,在陣列中將資料逆轉,再存放到連結串列中,不過這種方法太麻煩了,浪費時間空間,不推薦
//方法一:再建立一個連結串列_head,然後從頭遍歷原連結串列head,再將head中的資料以頭插法插入到_head連結串列中,這樣就完成了連結串列的逆轉
//方法二:三指標法,前提是至少有兩個資料,設定三個結構體指標p1、p2、p3,一開始p1指向頭結點,p2指向第二個節點,p3指向p2->next,此時對於我們來說,需要修改指向的是p2,
// p1是保留的上一個節點,p3是保留的下一個資料;在迴圈中,先判斷p2是否為空,不為空就讓p3=p2->next,然後修改p2指向為p1,更新p1、p2指向相對位置的下一個節點
//方法三:遞迴法,假設連結串列為:n1nk1nknk+1nm∅,現在需要修改nk+1的指向,我們可以不用管nk+1後面的指向,假設他們已經逆轉了,如n1nk1nknk+1nm
// 此時我們只需將nk+1的指向為nk,所以在進行遞迴時,需要先保留前一個節點nk,然後呼叫遞迴,等遞迴return之後,修改nk+1->next=nk;
// 遞迴的結束條件就是當前節點的next指向為空,就返回當前節點,注意,這個節點就將是逆置之後連結串列的頭結點,
// 需要注意的是,等遞迴完成之後,需要將head->next=NULL,否則連結串列將無法結束
//遞迴的函式 struct ListNode* func(struct ListNode* node){ if(node->next == NULL){ return node;//這裡返回的節點就是最終逆置好了的連結串列的頭結點 } struct ListNode* cur = node; node = node->next; struct ListNode* ret = func(node); node->next = cur; return ret; } struct ListNode* reverseList(struct
ListNode* head){ //遞迴的方法 if(head == NULL||head->next == NULL){ return head; } struct ListNode* ret = func(head); head->next = NULL; return ret; //頭插法 if(head == NULL||head->next ==NULL){ return head; } struct ListNode list; list.next
= NULL; struct ListNode* node = head; while(node){ struct ListNode* next = node->next; node->next = list.next; list.next = node; node = next; } return list.next; //三指標法 if(head == NULL||head->next ==NULL){ return head; } struct ListNode* p1 = NULL; struct ListNode* p2 = NULL; struct ListNode* p3 = NULL; p1 = head; p2 = p1->next; p1->next = NULL; while(p2){ p3 = p2->next; p2->next = p1; p1 = p2; p2 = p3; } return p1; }