鏈表相關筆試面試題

1.判斷兩個鏈表是否相交

????兩個鏈表是否相交可分為以下幾種情況
????(1)兩個鏈表都不帶環,此時兩個鏈表所對應的最后一個節點是相等的
????(2)兩個鏈表一個帶環,一個不帶環,兩個鏈表一定不相交
????(3)連個鏈表都帶環,如果相交則可以分為以下三種情況
???? ?1)兩個鏈表在環外相交, 此時鏈表1 和鏈表2 對應的環的入口地址是相等的
???? ?2)兩個鏈表在換上相交,此時從一個環的入口地址出發,一定可以到達另一個環的入口
???? ?3)如果不是以上兩種情況,則連個鏈表一定不相交

/***鏈表是否相交沒有環 **/int LinkListHasCrossWithCircle(LinkNode* head1, LinkNode* head2)
{if(head1 == NULL || head2 == NULL){return 0;}LinkNode* cur1 = head1;while(cur1 -> next != NULL){cur1 = cur1 -> next;}LinkNode* cur2 = head2;while(cur2 -> next != NULL){cur2 = cur2 -> next;}if(cur1 == cur2){return 1;}return 0;
}   /*** 鏈表是否相交,不確定有沒有環 **/int LinkListHasCrossWithCircle2(LinkNode* head1, LinkNode* head2)
{if(head1 == NULL || head2 == NULL){return 0;//兩鏈表至少一個為空}                                                                                                                                                          LinkNode* circle1 = LinkListHasCircle(head1);LinkNode* circle2 = LinkListHasCircle(head2);//兩個鏈表都不帶環if(circle1 == NULL && circle2 == NULL){return LinkListHasCrossWithCircle(head1, head2);}//兩鏈表都帶環else if(circle1 != NULL && circle2 != NULL){//在環外相交LinkNode* entry1 = LinkListGetCircleEntry(head1);LinkNode* entry2 = LinkListGetCircleEntry(head2);if(entry1 == entry2){return 1;}//再換上相交else if(entry1 != entry2){LinkNode* cur1 = entry1;//從一個環入口點出發可以到達另外一個環入口點,則證明相交while(cur1 != entry2){cur1 = cur1 -> next;}return 1;}//不是上述情況則沒有相交return 0;}//一個帶環一個不帶環,則一定不相交else if( ( circle1 == NULL && circle2 != NULL )|| (circle1 != NULL && circle2 == NULL)){return 0;}
}

???????????????????????這里寫圖片描述

2.求鏈表的交點

????求換的交點和上述判斷是否有環是一個思路,可以分為一下幾種情況
????(1)兩個鏈表都不帶環的情況下,先利用上面的函數判斷出連個鏈表是否相交,再求出兩個鏈表的長度 size1, size2,再將兩個鏈表的長度做差(長的減短的)得到一個大于等于0 的數 offset,再讓分別定義兩個指針 cur1, cur2, 指向 head1, head2, 然后讓長鏈表對應的 cur1(假定cur1所指的鏈表長) 先走 offset 步,cur2 不動,cur1 每走一步 offset 就減1, 等到 offset 等于 0 的時候這個時候就說明兩個指針cur1, cur2 都相對于交點的距離相等, 這個時候讓 cur1, cur2 一起向后走,當它們兩個指針所對應的節點相同時, 此時這個相同的節點就是兩個鏈表的交點
????(2)當兩個鏈表一個帶環,一個不帶環時, 此時鏈表一定不相交,直接返回空
????(3)當兩個鏈表都有環時,分為一下三種情況
????? 1)兩個鏈表在環外相交,此時的交點求法如圖所示

?????這里寫圖片描述
????? 2)連個鏈表在環上相交
?????????????????????????這里寫圖片描述
????? 3)如果不是以上兩種,那么一定不相交

/**                                                                                                                                                             *環的相交點不帶環**/LinkNode* LinkListCrossPoint(LinkNode* head1, LinkNode* head2)
{if(head1 == NULL || head2 == NULL){return NULL;//兩鏈表至少一個為空}int len1 = LinkListSize(head1);int len2 = LinkListSize(head2);LinkNode* cur1 = head1;LinkNode* cur2 = head2;int offset = 0;if(len1 > len2){offset = len1 - len2;for(; offset > 0; cur1 = cur1 -> next){offset--;}}else if(len2 > len1){offset = len2 - len1;for(; offset > 0; cur2 = cur2 -> next){offset--;}}for(; cur1 != cur2; cur1 = cur1 -> next, cur2 = cur2 -> next){;}return cur1;                                                                                                                                               
}/**                                                                                                                                                             *環的相交點帶環不帶環不確定**/LinkNode* LinkListCrossPoint2(LinkNode* head1, LinkNode* head2)
{if(head1 == NULL || head2 == NULL)                                                                                                                       {    return NULL;//兩鏈表至少一個為空,一定不相交}    LinkNode* entry1 = LinkListGetCircleEntry(head1);LinkNode* entry2 = LinkListGetCircleEntry(head2);//如果兩個都不帶環,直接用第一個版本if(entry1 == NULL && entry2 == NULL){    return LinkListCrossPoint(head1, head2);}    //如果一個帶環,一個不帶環,一定不相交if(( entry1 == NULL && entry2 != NULL ) || ( entry1 != NULL && entry2 == NULL )){    return NULL;}    //如果兩個都有環LinkNode* cur1 = head1;LinkNode* cur2 = head2;if(entry1 != NULL && entry2 != NULL){    
//環外相交if(entry1 == entry2){LinkNode* end = entry1;int size1 = 0;int size2 = 0;for(; cur1 != end; cur1 = cur1 -> next){size1++;}size1 = size1 + 1;for(; cur2 != end; cur2 = cur2 -> next){size2++;}size2 = size2 + 1;int offset =  0;if(size1 > size2){offset = size1 - size2;                                                                                                                      for(cur1 = head1, cur2 = head2; offset > 0; offset--){cur1 = cur1 -> next;}for(; cur1 != end && cur1 != cur2; cur1 = cur1 -> next, cur2 = cur2 -> next){;}return cur1;}else if(size2 > size1){offset = size2 - size1;for(cur1 = head1, cur2 = head2; offset > 0; offset--){cur2 = cur2 -> next;}for(; cur1 != end && cur1 != cur2; cur1 = cur1 -> next, cur2 = cur2 -> next){;}return cur1;}else//size1  = size2{for(cur1 = head1, cur2 = head2; cur1 != cur2 && cur1 != end && cur2 != end; cur1 = cur1 -> next, cur2 = cur2 -> next){                                                                                                                                            ;}return cur1;}}//環內相交,相交點就是入口else if(entry1 != entry2){LinkNode* cur = entry1;for(; cur != entry2; cur = cur -> next){;}return entry2;cur = entry2;for(; cur != entry1; cur = cur -> next){;}return entry1;}//不是上述兩種情況,則不相交else{return NULL;}                                                                                                                                                    }
}

????????????????這里寫圖片描述

3.求連個鏈表的交集

????求交集就是分別定義兩個指針 cur1, cur2,指向兩個對應的鏈表的首元素, 然后將 cur1 和 cur2 所指的鏈表的 data 進行比較, 如果相等, 將這個結點插入到一個新鏈表中, 然后兩個指針 cur1, cur2, 一起向后走一步,如果不相等, 就將 data 值小的那個指針向后移動, 而另外一個指針不動, 在進行比較,重復以上動作,直到 cur1 或者 cur2 兩個中其中一個為空,則停止循環

LinkNode* LinkListUnionSet(LinkNode* head1, LinkNode* head2)
{if(head1 == NULL || head2 == NULL){return NULL;//兩個鏈表至少有一個為空}LinkNode* cur1 = head1;LinkNode* cur2 = head2;LinkNode* new_head = NULL;LinkNode* new_tail = NULL;while(cur1 != NULL && cur2 != NULL){if(cur1 -> data < cur2 -> data){cur1 = cur1 -> next;}else if(cur1 -> data > cur2 -> data){cur2 = cur2 -> next;}else{if(new_head == NULL){new_head = LinkNodeCreat(cur1 -> data);new_tail = new_head;}else{new_tail -> next = LinkNodeCreat(cur1 -> data);new_tail = new_tail -> next;}cur1 = cur1 -> next;                                                                                                                               cur2 = cur2 -> next;}}return new_head;
}

這里寫圖片描述

4. 拷貝復雜鏈表

????先看一下復雜鏈表的數據結構

typedef struct ComplexNode
{LinkNodeType data;struct ComplexNode* next;struct ComplexNode* random;
}ComplexNode;

????復雜鏈表中除了 data, next, 之外,還有一個 random, 它可能指向鏈表中的如何一個節點, 還可能指向空。
????在進行復雜鏈表的拷貝時, 可以采用下面的方法, 先將復雜鏈表按照簡單鏈表進行復制,將其復制到一個新鏈表中, 此時的新鏈表還是一個簡單鏈表, 然后再遍歷舊鏈表,求出每一個節點所對應的 random 相對于頭節點的偏移量, 再遍歷新鏈表, 根據所求得的偏移量確定新鏈表中的 random 的指針的指向。

/*** 復雜鏈表的拷貝**/                                                                                                                                                            ComplexNode* ComplexCopy(ComplexNode* head)
{if(head == NULL){return NULL;//空鏈表}ComplexNode* cur = head;ComplexNode* new_head = NULL;ComplexNode* new_tail = NULL;while(cur != NULL){if(new_head == NULL){new_head = head ;new_tail = new_head;}else{new_tail -> next = cur;new_tail = new_tail -> next;}cur = cur -> next;}//求每個random相對于頭結點的偏移量int offset = 0;ComplexNode* new_cur = new_head;for(cur = head; cur != NULL; cur = cur -> next,new_cur = new_cur -> next){//求出每個結點相對于head的偏移量offset = Diff(head, cur -> random);//修改新鏈表中的random的值new_cur -> random = Step(new_head, offset);}return new_head;
}/*                                                                                                                                                             ** 通過offset找到random**/ComplexNode* Step(ComplexNode* head, int offset)
{if(head == NULL){    return NULL;//空鏈表}    if(offset == -1){    return NULL;}    ComplexNode* cur = head;ComplexNode* random = head;//讓 random 走 offset 步,再將 cur -> random = randomfor(; offset > 0; offset --){    random = random -> next;}    return random; 
}/*** 求出每個結點相對于head的偏移量**/int Diff(ComplexNode* head, ComplexNode* random)
{if(head == NULL){return -2;}if(random == NULL){return -1;}ComplexNode* cur = head;ComplexNode* new_cur = random;int count = 0;while(cur != new_cur){count++;cur = cur -> next;}return count;
}

這里寫圖片描述

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

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

相關文章

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…

C++實現String類

http://blog.csdn.net/randyjiawenjie/article/details/6709539 C實現String類&#xff0c;還沒有完成&#xff0c;待繼續。 有以下注意的點&#xff1a; &#xff08;1&#xff09;賦值操作符返回的是一個MyString&&#xff0c;而重載的返回的是一個MyString。其中的原因…

POJ 3370 Halloween treats——鴿巢原理+思維

【題目描述】 POJ 3370 Halloween treats Description Every year there is the same problem at Halloween: Each neighbour is only willing to give a certain total number of sweets on that day, no matter how many children call on him, so it may happen that a chi…

將信號量代碼生成靜態庫以及動態庫

1.信號量相關代碼生成靜態庫 2.信號量相關代碼生成動態庫

Wormholes——Bellman-Ford判斷負環

【題目描述】 While exploring his many farms, Farmer John has discovered a number of amazing wormholes. A wormhole is very peculiar because it is a one-way path that delivers you to its destination at a time that is BEFORE you entered the wormhole! Each of…

C++11 標準新特性:Defaulted 和 Deleted 函數

https://www.ibm.com/developerworks/cn/aix/library/1212_lufang_c11new/index.html Defaulted 函數 背景問題 C 的類有四類特殊成員函數&#xff0c;它們分別是&#xff1a;默認構造函數、析構函數、拷貝構造函數以及拷貝賦值運算符。這些類的特殊成員函數負責創建、初始化、…

順序表實現棧相關操作

1.棧的相關概念 棧是一種特殊的線性表, 其中只允許在固定的一端進行插入和刪除元素.進行數據插入和刪除的一端叫做棧頂, 另一端成為棧底. 不含任何元素的棧稱為空棧, 棧又稱為先進先出的線性表. 2. 順序棧的結構 3. 順序棧的具體操作 (1). 數據結構 typedef char SeqStackTyp…

MPI Maelstrom——Dijkstra

【題目描述】 BIT has recently taken delivery of their new supercomputer, a 32 processor Apollo Odyssey distributed shared memory machine with a hierarchical communication subsystem. Valentine McKee’s research advisor, Jack Swigert, has asked her to bench…

雙向帶環帶頭結點的鏈表實現棧

1. 數據結構 利用帶頭結點帶環的結點實現棧的相關操作.因此, 每一個結點包括了一個前驅, 一個后繼, 還有一個數據成員 typedef char DLinkStackType;typedef struct DLinkStack {DLinkStackType data;struct DLinkStack* next;struct DLinkStack* prev; }DLinkStack;2. 初始化…

Cow Contest——Floyed+連通性判斷

【題目描述】 N (1 ≤ N ≤ 100) cows, conveniently numbered 1…N, are participating in a programming contest. As we all know, some cows code better than others. Each cow has a certain constant skill rating that is unique among the competitors. The contest …

C++11 標準新特性:委派構造函數

https://www.ibm.com/developerworks/cn/rational/1508_chenjing_c11/index.html陳 晶2015 年 8 月 11 日發布WeiboGoogle用電子郵件發送本頁面 1本文首先介紹了在委派構造函數提出之前類成員構造所面臨的問題&#xff0c;再結合實例介紹了委派構造函數的用法&#xff0c;并說明…

順序表實現隊列

一. 隊列相關概念 隊列是只允許在一段進行插入元素, 在另一端進行刪除元素的線性表,即只允許對隊列進行尾插,頭刪的操作.隊列具有先進先出, 后進后出的特性. ???????? 1.初始化 void SeqQueInit(SeqQue* q) {if(q NULL){return;//非法輸入}q -> head 0;q -> …

Arbitrage——判斷正環Bellman-Ford/SPFA

【題目描述】 Arbitrage is the use of discrepancies in currency exchange rates to transform one unit of a currency into more than one unit of the same currency. For example, suppose that 1 US Dollar buys 0.5 British pound, 1 British pound buys 10.0 French …