逆轉(zhuǎn)交替合并兩個(gè)鏈表的解析與實(shí)現(xiàn)
逆轉(zhuǎn)交替合并兩個(gè)鏈表,即從一個(gè)鏈表的尾指針指向另一個(gè)鏈表的尾指針,依次逆轉(zhuǎn)交替進(jìn)行合并。下面就通過(guò)實(shí)例來(lái)詳細(xì)的介紹該逆轉(zhuǎn)交替合并兩個(gè)鏈表的思路與實(shí)現(xiàn)代碼。
一、問(wèn)題描述
鏈表A和B
A: 1->2->3->4
B: a->b->c->d
請(qǐng)逆轉(zhuǎn)交替合并兩個(gè)鏈表,示例結(jié)果如下:
4->d->3->c->2->b->1->a
節(jié)點(diǎn)類(lèi)型定義如下:
classNode {
public Node next;
...
}
二、源代碼:
傳入兩個(gè)A和B鏈表,返回處理后的鏈表:
Node reverse_merge(Node A, Node B)
{
//A、B都只有一個(gè)節(jié)點(diǎn)
if(A.next==null)
{
A.next=B;
return A;
}
//A、B都大于等于2個(gè)節(jié)點(diǎn)
Node nextA;
Node nextB;
nextB = B.next;
B.next = null;
nextA = A.next;
A.next = B;
B = nextB;
while (nextA.next != null)
{
B.next = A;
A = nextA;
nextA = A.next;
A.next = B;
B = nextB;
}
nextB.next = A;
nextA.next = B;
return nextA;
}
三、解析:
程序分成三個(gè)部分——while循環(huán)之前、while循環(huán)體、while循環(huán)之后。
1)處理之前的鏈表A和B

2)while循環(huán)——核心的處理部分
這里處理程序的可重復(fù)的部分,我們的目標(biāo)是紅色的部分,要達(dá)成紅色的鏈接模式,有兩個(gè)原子結(jié)構(gòu):深紅色圓圈1和藍(lán)色圓圈2

但是1中需要特別處理a所在的節(jié)點(diǎn),僅對(duì)于a所在的節(jié)點(diǎn)需要一個(gè)next=null的操作,也就是說(shuō)1中的第一個(gè)原子要放在循環(huán)之外實(shí)現(xiàn),這包括1指向a,b指向1的操作。
換種方式,如果使用2方式,就只需要將1指向a放在循環(huán)之外。所以,這里采用了2中描述的原子結(jié)構(gòu)。
原子結(jié)構(gòu)需要的信息
當(dāng)我們進(jìn)行到某一次循環(huán)時(shí),假設(shè)進(jìn)行到藍(lán)色圓圈的操作了,這時(shí)候我們鏈表的狀態(tài)為:

更為直觀的畫(huà)法為:

它涉及到3個(gè)節(jié)點(diǎn)——2,3和c。其中紅色部分是我們希望做到的鏈接方式。為了鏈接c->2,3->c,必須知道有相應(yīng)的指針記錄他們的位置。所以在循環(huán)之前我們需要掌握這三個(gè)元素的地址,并且在處理完之后,用相同的方式表示下一次需要處理的原子結(jié)構(gòu)。
例如以下這種方式記錄這次循環(huán)中設(shè)計(jì)的3個(gè)節(jié)點(diǎn)的地址:

A、nA、B代表指向相應(yīng)節(jié)點(diǎn)的指針或者說(shuō)是引用。
在處理完成之后需要用相同的方式記錄下一次原子結(jié)構(gòu)涉及的節(jié)點(diǎn),這樣才能保證循環(huán)能夠按統(tǒng)一邏輯執(zhí)行下去,我們的目標(biāo)是:

這些賦值操作正是循環(huán)體的中代碼所做的事情,恰好代碼也是按照上面指定的命名形式,有一點(diǎn)區(qū)別,圖中的nA代表代碼中的nextA。除此之外,代碼中定義了nextB作為一個(gè)中間變量,用來(lái)記錄c->d斷開(kāi)之前d節(jié)點(diǎn)的地址,因?yàn)閏指向2之后就會(huì)失去對(duì)d的聯(lián)系,這個(gè)中間變量是必須的。
3)while循環(huán)之前——解決預(yù)備操作所帶來(lái)的問(wèn)題
我們還沒(méi)有處理a節(jié)點(diǎn),因?yàn)樗厥饬耍瑳](méi)有合適的原子結(jié)構(gòu)能包括它。所以我們把它放在循環(huán)體之外,并且為循環(huán)做好準(zhǔn)備工作,我們希望的結(jié)果是這樣:

在這之后我們就可以把1,2,b放在循環(huán)體中處理。這里也考慮了A、B都只有一個(gè)節(jié)點(diǎn)的情況,也需要單獨(dú)處理。
4)while循環(huán)之后——最后的處理
當(dāng)我們發(fā)現(xiàn)B鏈表到達(dá)末尾時(shí),結(jié)束循環(huán)。但這時(shí)候并有處理末尾節(jié)點(diǎn),換句話說(shuō),末尾節(jié)點(diǎn)不在原子結(jié)構(gòu)中。我們的循環(huán)會(huì)停止在這個(gè)原子結(jié)構(gòu)中:

作為最后的操作,我們需要手動(dòng)處理d->3,4->d的鏈接步驟——這也是沒(méi)有辦法的,因?yàn)樵咏Y(jié)構(gòu)的處理必須找到能夠把所有指針傳遞下去的節(jié)點(diǎn),作為最后的節(jié)點(diǎn)是沒(méi)辦法吧指針繼續(xù)傳遞下去。
這不是一個(gè)完整的方法,還有很多事情沒(méi)有處理,比如輸入的A、B如果不等長(zhǎng),應(yīng)該如何處理。另外Node數(shù)據(jù)結(jié)構(gòu)并沒(méi)有完整的定義,不過(guò)這都不是本文討論的重點(diǎn)。
通過(guò)以上詳細(xì)的解析,希望能夠幫助大家很好的理解該逆轉(zhuǎn)交替合并兩個(gè)鏈表的方法與實(shí)現(xiàn)。
- 探討:將兩個(gè)鏈表非降序合并為一個(gè)鏈表并依然有序的實(shí)現(xiàn)方法
- Java采用循環(huán)鏈表結(jié)構(gòu)求解約瑟夫問(wèn)題
- C語(yǔ)言實(shí)現(xiàn)雙向鏈表
- JavaScript實(shí)現(xiàn)的鏈表數(shù)據(jù)結(jié)構(gòu)實(shí)例
- C++語(yǔ)言實(shí)現(xiàn)線性表之鏈表實(shí)例
- C#通過(guò)鏈表實(shí)現(xiàn)隊(duì)列的方法
- C++實(shí)現(xiàn)的鏈表類(lèi)實(shí)例
- JavaScript中數(shù)據(jù)結(jié)構(gòu)與算法(三):鏈表
相關(guān)文章
詳解Java 中的嵌套類(lèi)與內(nèi)部類(lèi)
這篇文章主要介紹了詳解Java 中的嵌套類(lèi)與內(nèi)部類(lèi)的相關(guān)資料,希望通過(guò)本文大家能掌握J(rèn)ava 嵌套類(lèi)與內(nèi)部類(lèi)的使用方法,需要的朋友可以參考下2017-09-09
SpringBoot使用MyBatis實(shí)現(xiàn)數(shù)據(jù)的CRUD
MyBatis是一個(gè)輕量級(jí)的對(duì)象關(guān)系映射(Object-Relational Mapping,ORM)框架,它允許開(kāi)發(fā)者通過(guò)編寫(xiě)SQL動(dòng)態(tài)查詢(xún)數(shù)據(jù)庫(kù),而無(wú)需顯式地操作JDBC,對(duì)于增刪改查操作,MyBatis提供了一種基于XML或注解的方式來(lái)進(jìn)行,本文介紹了SpringBoot使用MyBatis實(shí)現(xiàn)數(shù)據(jù)的CRUD2024-11-11
Spring Boot如何優(yōu)化內(nèi)嵌的Tomcat示例詳解
spring boot默認(rèn)web程序啟用tomcat內(nèi)嵌容器,監(jiān)聽(tīng)8080端口,下面這篇文章主要給大家介紹了關(guān)于Spring Boot如何優(yōu)化內(nèi)嵌Tomcat的相關(guān)資料,文中通過(guò)示例代碼介紹的非常詳細(xì),需要的朋友可以參考借鑒,下面來(lái)一起看看吧。2017-09-09
Spring?Boot項(xiàng)目中使用OpenAI-Java的示例詳解
Spring?Boot是由Pivotal團(tuán)隊(duì)提供的全新框架,其設(shè)計(jì)目的是用來(lái)簡(jiǎn)化新Spring應(yīng)用的初始搭建以及開(kāi)發(fā)過(guò)程,這篇文章主要介紹了Spring?Boot項(xiàng)目中使用OpenAI-Java的示例詳解,需要的朋友可以參考下2023-04-04
springmvc后臺(tái)基于@ModelAttribute獲取表單提交的數(shù)據(jù)
這篇文章主要介紹了springmvc后臺(tái)基于@ModelAttribute獲取表單提交的數(shù)據(jù),文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下2019-10-10
JAVA Spring中讓人頭痛的JAVA大事務(wù)問(wèn)題要如何解決你知道嗎
這篇文章主要介紹了Java Spring事務(wù)使用及驗(yàn)證過(guò)程詳解,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下2021-09-09
IDEA創(chuàng)建javaee項(xiàng)目依賴(lài)war exploded變紅失效的解決方案
在使用IntelliJ IDEA創(chuàng)建JavaEE項(xiàng)目時(shí),可能會(huì)遇到Tomcat部署的warexploded文件出現(xiàn)問(wèn)題,解決方法是首先刪除有問(wèn)題的warexploded依賴(lài),然后根據(jù)圖示重新導(dǎo)入項(xiàng)目,此外,調(diào)整虛擬路徑有時(shí)也能有效解決問(wèn)題2024-09-09
java獲取登錄者IP和登錄時(shí)間的兩種實(shí)現(xiàn)代碼詳解
這篇文章主要介紹了java獲取登錄者IP和登錄時(shí)間的實(shí)現(xiàn)代碼,本文通過(guò)兩種結(jié)合實(shí)例代碼給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下2020-07-07
如何在Spring?Boot中使用MyBatis訪問(wèn)數(shù)據(jù)庫(kù)
MyBatis可以通過(guò)簡(jiǎn)單的XML或者注解來(lái)配置和映射原始類(lèi)型,接口,和Java POJO為數(shù)據(jù)庫(kù)中記錄,使用MyBatis幫助我們解決各種問(wèn)題,本文介紹如何在Spring?Boot中使用MyBatis訪問(wèn)數(shù)據(jù)庫(kù),感興趣的朋友一起看看吧2023-11-11
itext生成PDF設(shè)置頁(yè)眉頁(yè)腳的實(shí)例詳解
這篇文章主要介紹了itext生成PDF設(shè)置頁(yè)眉頁(yè)腳的實(shí)例詳解的相關(guān)資料,希望通過(guò)本文能幫助到大家,需要的朋友可以參考下2017-09-09

