單鏈表的相關操作

1.冒泡排序對單鏈表進行排序
void LinkListBubbleSort(LinkNode* head)
{if(head == NULL){    return;//空鏈表}    if(head -> next == NULL){    return;//只有一個結點}    LinkNode* cur = head;//趟數LinkNode* tail = NULL;//尾指針LinkNode* tmp = head;//次數for(; cur -> next != NULL; cur = cur -> next){    for(tmp = head; tmp -> next != tail; tmp = tmp -> next){    if(tmp -> data > tmp -> next -> data){    LinkNodeSwap(&tmp -> data, &tmp -> next -> data);}                                                                                                                                                }    tail = tmp; }    
}

????其中cur控制總共需要幾趟,N個元素需要N-1趟排序, tmp控制一趟需要進行幾次比較
這里寫圖片描述
這里寫圖片描述
這里寫圖片描述
這里寫圖片描述
這里寫圖片描述

2.將兩個已經排好序的單鏈表進行合并,并且保證新鏈表有序
LinkNode* LinkListMerge(LinkNode* head1, LinkNode* head2)
{                                                                                                                                                            if(head1 == NULL){return head2;}if(head2 == NULL){return head1;}LinkNode* new_head;LinkListInit(&new_head);LinkNode* cur1 = head1;LinkNode* cur2 = head2;while(cur1 != NULL && cur2 != NULL){if(cur1 -> data > cur2 -> data){LinkListPushBack(&new_head, cur1 -> data);cur1 = cur1 -> next;}else{LinkListPushBack(&new_head, cur2 -> data);cur2 = cur2 -> next;}}while(cur2 != NULL){LinkListPushBack(&new_head, cur2 -> data);cur2 = cur2 -> next;}while(cur1 != NULL){LinkListPushBack(&new_head, cur1 -> data);cur1 = cur1 -> next;}return new_head;
}

????假設待排序列如下圖
這里寫圖片描述
????那就創建一個新鏈表,將其初始化,每次將cur1 和 cur2 作比較,在保證 cur1 和 cur2 兩個指針都不為空的前提下將它們兩個中 data 小的插入到新鏈表的尾部就可以同時 cur1 和 cur2 往后移動,當 cur1 為空, cur2 不為空時就將 cur2 的剩下的所有元素依次全部搬到新鏈表中.
這里寫圖片描述
這里寫圖片描述

3.查找單鏈表中間結點,并且保證只能遍歷一次鏈表

LinkNode* LinkListFindMid(LinkNode* head)
{if(head == NULL){return NULL;}if(head -> next == NULL || head -> next -> next == NULL){return head;}LinkNode* fast = head;LinkNode* slow = head;while(fast != NULL && fast -> next != NULL){fast = fast -> next -> next;slow = slow -> next;                                                                                                                                 }return slow;
}

????定義兩個指針 fas t, slow ,在保證 fast 不為空并且 fast -> next 不為空的前提下,讓 fast 一次走兩步,slow一次走一步, 當 fast 走到 空的時候 slow 就剛好處于中間,此時返回 slow 就可以了
這里寫圖片描述
????????????????這里寫圖片描述

4.找鏈表的倒數第 k 個結點
LinkNode* LinkListFindLastKNode(LinkNode* head, int K)
{if(head == NULL){return NULL;//空鏈表}int count = 0;LinkNode* cur = head;while(cur != NULL){count ++;cur = cur -> next;}if(K > count){return NULL;//K值大于節點個數}LinkNode* slow = head;LinkNode* fast = head;int i = 0;for(; i < K; i ++){                                                                                                                                                        if(fast != NULL){fast = fast -> next;}}while(fast != NULL){slow = slow -> next;fast = fast -> next;}return slow;
}

????同樣,定義兩個指針, fast 和 slow, 讓 fast 先走 k 步, 然后 fas 走一步,slow跟著走一步,當 fast 等于空的時候 slow 剛好是倒數第 k 個結點
這里寫圖片描述
這里寫圖片描述
這里寫圖片描述
????????????????這里寫圖片描述

4.刪除鏈表的倒數第 k 個結點
void LinkListEraseLastKNode(LinkNode** phead, int K)
{if(phead == NULL){return;//非法輸入}if(*phead == NULL){                                                                                                                                                        return;//空鏈表}int count = 0;LinkNode* cur = *phead;while(cur != NULL){count++;cur = cur -> next;}if(K > count){return;//K大于結點個數}if(K == count){LinkListPopFront(phead);return;}LinkNode* to_delete = LinkListFindLastKNode(*phead, K + 1);LinkListEraser(phead, to_delete -> next);
}

????利用前面的算法找到倒數第 k + 1個結點, 然后刪除第 k + 1 個結點的下一個結點即可
這里寫圖片描述

5.約瑟夫環問題
LinkNode* LinkListJosephCircle(LinkNode** phead, int M)
{if(phead == NULL){                                                                                                                                                          return NULL;//非法輸入}if(*phead == NULL){return NULL;//鏈表為空}if((*phead) -> next == *phead){return *phead;//只有一個元素}LinkNode* cur = *phead;LinkNode* to_delete;int i = 0;while(cur -> next != cur){for(i = 1; i < M; i ++){cur = cur -> next;}cur -> data = (cur -> next) -> data;to_delete = cur -> next;cur -> next = to_delete -> next;LinkNodeDestroy(&to_delete);}return cur;
}

????對于約瑟夫環問題先將這個鏈表形成一個帶環的鏈表,即最后一個結點的 next 指向第一個結點,然后從第一個結點遍歷這個鏈表,當遍歷到第M個結點時就把這個結點刪除,注意當給定目標是M是,指針移動M - 1次, 當指針移動M-1次時,就定義一個指針to_delete指向要刪除的這個元素,然后刪除這個元素,如此繼續,直到剩余一個結點,即cur -> next = cur 時,就返回這個結點
?????????????這里寫圖片描述

6.逆序打印單鏈表
void LinkListReversePrint(LinkNode* phead)
{if(phead == NULL) {return;}                                                                                                                                                           LinkListReversePrint(phead -> next);printf("%c   ", phead -> data);
}

????對于逆序打印單鏈表,采用遞歸的思想,即讓指針往后遍歷整個鏈表,直到最后一個時再將其對應的 data 打印出來即可
這里寫圖片描述
這里寫圖片描述
這里寫圖片描述

7.單鏈表的逆置
void LinkListReverse(LinkNode** phead)
{if(phead == NULL){    return;//非法輸入}    if(*phead == NULL){    return;//鏈表為空}    if((*phead) -> next == NULL){    return;//只有一個元素}    LinkNode* cur = *phead;LinkNode* to_delete = cur; while(cur -> next != NULL){    to_delete = cur -> next;cur -> next = to_delete -> next;to_delete -> next = *phead;*phead = to_delete;                                                                                                                                    }    
}

????這里寫圖片描述

8.判斷鏈表是否有環
LinkNode* LinkListHasCircle(LinkNode* head)
{if(head == NULL)                                                                                                                                           {    return NULL;//空鏈表}    if(head -> next == NULL){    return NULL;//一個結點并且無環}    LinkNode* fast = head;LinkNode* slow = head;while(fast != NULL && fast -> next != NULL){    fast = fast -> next -> next;slow = slow -> next;if(slow == fast){    return slow;}    }    return NULL;
}

????先構造一個有環的鏈表,然后定義兩個指針 fast 和 slow, 在保證 fast 不為空, 以及fast -> next 不為空的前提下,fast一次走兩步,slow一次走一步,如果有環,在一定時間內 fast 一定會追上 slow ,即 fast = slow,當遇到 fast 為空時,那就說明沒有環
??????????????????這里寫圖片描述

9.求環的長度
int LinkListGetCircleLength(LinkNode* head)
{if(head == NULL){    return 0;//空鏈表}    if(head -> next == NULL){    return 0;//只有一個結點,沒有環}    LinkNode* meet = LinkListHasCircle(head);LinkNode* slow = meet;int size = 0; while(slow -> next != meet){    size ++;slow = slow -> next;}    return size + 1; 
}

????定義一個快指針fast,一個慢指針slow,fast一次走兩步, slow一次走一步,當兩者相遇時定義一個指針meet記住這個位置, 然后讓slow繼續往前走,同時定義一個計數器進行計數count,當slow的next等于meet時候,此時count+1便是換的長度
?????????????????這里寫圖片描述

10.求環的入口點
LinkNode* LinkListGetCircleEntry(LinkNode* head)
{if(head == NULL){    return NULL;//空鏈表                                                                                                                                   }    if(head -> next == NULL){    return NULL;//只有一個結點,并且沒有環}    LinkNode* meet = LinkListHasCircle(head);if(meet == NULL){    return NULL;}    LinkNode* slow = head;LinkNode* fast = meet;while(slow != fast){    slow = slow -> next;fast = fast -> next;}    return slow;
}

????還是快慢指針,鏈表開始到環入口的距離等于快慢指針相遇點到環入口的距離,即定義一個指針fast等于快慢指針相遇的那個位置,再定義一個指針slow等于head,然后兩個指針一次向后遍歷,當fast = slow 的之后,返回這個位置,便是環入口的位置
????????????????????這里寫圖片描述

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

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

相關文章

socket網絡編程--epoll小結

http://www.cnblogs.com/wunaozai/p/3895860.html 以前使用的用于I/O多路復用為了方便就使用select函數&#xff0c;但select這個函數是有缺陷的。因為它所支持的并發連接數是有限的(一般小于1024)&#xff0c;因為用戶處理的數組是使用硬編碼的。這個最大值為FD_SETSIZE&#…

進程間通信(匿名管道)

1.進程通信的目的 (1) 數據傳輸: 一個進程需要將它的數據傳輸給另一個進程 ????(2) 資源共享: 多個進程之間共享同樣的資源 ????(3) 通知事件: 一個進程需要向另一個或一組進程發送消息, 通知它們發生了什么事情 2.管道 管道是一種進程之間通信的一種方式, 我們把從…

線性基入門

今天學習了神奇的線性基&#xff0c;主要是在解決異或問題時比較有用。 詳細的解釋和證明有大佬珠玉在前&#xff0c;如果感興趣可以移步 補充一下自己的理解&#xff1a; 可以聯系線性代數極大無關組進行理解&#xff0c;線性基就相當于異或的向量空間中的極大無關組&#xff…

單例模式及C++實現代碼

http://www.cnblogs.com/cxjchen/p/3148582.html 單例模式 單例模式&#xff0c;可以說設計模式中最常應用的一種模式了&#xff0c;據說也是面試官最喜歡的題目。但是如果沒有學過設計模式的人&#xff0c;可能不會想到要去應用單例模式&#xff0c;面對單例模式適用的情況&am…

UVALive - 8512——線段樹維護線性基

【題目描述】 UVALive - 8512XOR 【題目分析】 這種區間線性基的問題我們可以考慮用線段樹維護&#xff0c;線性基的合并的話就直接暴力合并 找到所在區間的線性基后再查找最大的數&#xff0c;我看網上的博客要說消除k的影響什么的&#xff0c;我覺得沒有什么必要&#xff0c;…

命名管道

1.命名管道的創建 (1) 通過命令創建 mkfifo filename (2)在程序中創建 int mkfifo(const char* filename, mode_t mode); 2. 命名管道和匿名管道的區別 (1)匿名管道由pipe函數創建并且打開 ????(2)命名管道有mkfifo函數創建由open函數打開 ????(3) fifo 之間的兩…

HYSBZ - 1101——莫比烏斯反演

【題目描述】 HYSBZ - 1101 【題目分析】 昨天測試出了一道差不多的題目&#xff0c;我只能想到暴力&#xff0c;各種優化&#xff0c;最后都是運行了好久TLE&#xff0c;最后才知道要用到莫比烏斯反演&#xff0c;就想著今天研究一下&#xff0c;得出的結論就是&#xff0c;我…

Linux下I/O多路轉接之select --fd_set

http://blog.csdn.net/li_ning_/article/details/52165993 fd_set 你終于還是來了&#xff0c;能看到這個標題進來的&#xff0c;我想&#xff0c;你一定是和我遇到了一樣的問題&#xff0c;一樣的疑惑&#xff0c;接下來幾個小時&#xff0c;我一定竭盡全力&#xff0c;寫出我…

BZOJ 2844 | HYSBZ - 2844albus就是要第一個出場——線性基

【題目描述】 BZOJ 2844 | HYSBZ - 2844albus 【題目分析】 題目的意思大概是給一個數列&#xff0c;他有2n個子集&#xff0c;每個子集的元素的異或和構成新的一個數列&#xff0c;排序后問數字Q在這個序列里面的下標。 假如題目是求所有元素的異或和構成一個集合就好弄了&…

CodeForces - 641ELittle Artem and Time Machine——map+樹狀數組

【題目描述】 CodeForces - 641ELittle Artem and Time Machine 【題目分析】 題目的意思大概是有三種操作 1.在時間t加入一個數字x 2.在時間t刪除一個數字x 3.詢問在時間t集合里面x的個數 雖然題目描述很簡單&#xff0c;但是t和x的范圍都是109&#xff0c;我一開始想到的是主…

I/O多路轉接之poll 函數

http://blog.csdn.net/li_ning_/article/details/52167224 poll 一、poll()函數&#xff1a; 這個函數是某些Unix系統提供的用于執行與select()函數同等功能的函數&#xff0c;自認為poll和select大同小異&#xff0c;下面是這個函數的聲明&#xff1a; [cpp] view plaincopy …

鏈表相關筆試面試題

1.判斷兩個鏈表是否相交 兩個鏈表是否相交可分為以下幾種情況 ????&#xff08;1&#xff09;兩個鏈表都不帶環&#xff0c;此時兩個鏈表所對應的最后一個節點是相等的 ????&#xff08;2&#xff09;兩個鏈表一個帶環&#xff0c;一個不帶環&#xff0c;兩個鏈表一定…

Linux經典問題—五哲學家就餐問題

http://m.blog.csdn.net/aspenstars/article/details/70149038 一、問題介紹 由Dijkstra提出并解決的哲學家進餐問題(The Dinning Philosophers Problem)是典型的同步問題。該問題是描述有五個哲學家共用一張圓桌&#xff0c;分別坐在周圍的五張椅子上&#xff0c;在圓桌上有五…

修改之前的myshell使之支持輸入輸出重定向

1.open函數 ????這個函數是打開一個文件&#xff08;文件名叫pathname),以 flag 權限打開&#xff0c;flag 包括了以下幾種 O_RDONLY&#xff08;只讀&#xff09;, O_WRONLY&#xff08;只寫&#xff09;, O_RDWR&#xff08;讀寫&#xff09;&#xff0c;當文件打開成…

HDU - 6621 K-th Closest Distance——主席樹+二分

【題目描述】 HDU - 6621 K-th Closest Distance 【題目分析】 因為看到第kkk大的要求&#xff0c;剛開始的時候一直都在想怎么運用第kkk大來解決問題&#xff0c;但是后來看其他人的博客才發現并不需要用第k大&#xff0c;但是主席樹維護權值線段樹還是需要的&#xff0c;這…

鏈表相關的算法題大匯總 — 數據結構之鏈表奇思妙想

http://blog.csdn.net/lanxuezaipiao/article/details/22100021基本函數&#xff08;具體代碼實現見后面&#xff09; 1&#xff0c;構造節點 //定義節點類型 struct Node { int value; Node*next; }; 2&#xff0c;分配節點 //之所以要分配節點原因是需要在分配函數中…

CodeForces - 372CWatching Fireworks is Fun+DP+單調隊列優化

【題目描述】 CodeForces - 372CWatching Fireworks is Fun 題目的大概意思就是在一個編號為1…n的街道上現在按照時間順序放煙花&#xff0c;每個煙花獲得的幸福感為b?abs(a?x)b-abs(a-x)b?abs(a?x)&#xff0c;x為觀看煙花的位置&#xff0c;為了提升我們的幸福感&#x…

雙向鏈表的基本操作

1.雙向鏈表的數據結構 typedef char DLinkType;typedef struct DLinkNode { DLinkType data; struct DLinkNode* next; struct DLinkNode* prev; }DLinkNode; 雙向帶頭結點的鏈表有三個成員&#xff0c; 一個是數據&#xff0c; 一個是指針 next 指向當前結點的下一個結點&…

匿名管道

1.進程通信的目的 (1) 數據傳輸: 一個進程需要將它的數據傳輸給另一個進程 ????(2) 資源共享: 多個進程之間共享同樣的資源 ????(3) 通知事件: 一個進程需要向另一個或一組進程發送消息, 通知它們發生了什么事情 2.管道 管道是一種進程之間通信的一種方式, 我們把從…

Currency Exchange——最短路Bellman-Ford算法

【題目描述】 Several currency exchange points are working in our city. Let us suppose that each point specializes in two particular currencies and performs exchange operations only with these currencies. There can be several points specializing in the sam…