python算法-002單鏈表逆序遞歸法

上一篇文章也講的單鏈表的逆序,但我沒有詳細(xì)的將過程寫出來望忆。這讓讀者不能夠更加快速的理解我寫的代碼的原理吴叶,是我的疏忽阐虚,以后會(huì)慢慢改進(jìn)。今天看的一篇文章中說蚌卤,“如果我能寫出清晰的注釋和技術(shù)規(guī)格說明書实束,其他程序員能夠理解我的代碼奥秆,因此他們就能在自己的代碼中使用,而不用重寫咸灿。如果我做不到這一點(diǎn)构订,那我的代碼對(duì)其他人就沒有價(jià)值”苁福”看到這話悼瘾,我心里一顫,上一篇文章簡(jiǎn)直就是一坨shi审胸。


好了亥宿,廢話不多說,進(jìn)入正題歹嘹。

題目:給定一個(gè)帶頭節(jié)點(diǎn)的單鏈表:head->1->2->3->4->5->6->7->8箩绍;使其成為:head->8->7->6->5->4->3->2->1孔庭。

這次題目與上次一樣是將單鏈表逆序尺上。鏈表是一種在學(xué)習(xí)、編寫程序等時(shí)用的非常多的數(shù)據(jù)結(jié)構(gòu)圆到。我們這里研究的鏈表是單鏈表怎抛,而單鏈表又有帶頭節(jié)點(diǎn)和不帶頭節(jié)點(diǎn)兩種。

這里給出帶頭節(jié)點(diǎn)的鏈表的建立方法:由N個(gè)節(jié)點(diǎn)鏈在一起的叫鏈表芽淡,當(dāng)節(jié)點(diǎn)只包含自身存儲(chǔ)的數(shù)據(jù)以及其后繼節(jié)點(diǎn)的信息的鏈表叫單鏈表马绝。python中沒有指針的概念,但是引用的功能類似于指針挣菲,所以用引用來建立節(jié)點(diǎn)之間的關(guān)系富稻,為了方便理解,之后的文章可能會(huì)用指針來描述白胀。
節(jié)點(diǎn)的數(shù)據(jù)域用data表示椭赋,其后繼節(jié)點(diǎn)域用next表示:

#先建立節(jié)點(diǎn)對(duì)象LNode
class LNode:
    def __init__(self,arg):
        # 這是數(shù)據(jù)域data
        self.data = arg    
        # 這是節(jié)點(diǎn)的next域,也就是下一個(gè)節(jié)點(diǎn)的引用
        self.next = None  
"""
方法功能:創(chuàng)建一個(gè)帶頭節(jié)點(diǎn)的單鏈表
"""
def creatLink(x):
    #  x是鏈表的長(zhǎng)度 
    i = 1
    head = LNode(None) # 先構(gòu)造單鏈表的頭節(jié)點(diǎn)
    tmp = None # 用來指向新添加的節(jié)點(diǎn)
    cur = head # 用來指向鏈表的最后一個(gè)節(jié)點(diǎn)
    while i <= x:
        tmp = LNode(i)
        cur.next = tmp
        cur = tmp
        i += 1
    return head

這次我們使用遞歸法來實(shí)現(xiàn): 遞歸程序有兩個(gè)要素:一是遞歸定義或杠,一是遞歸終止條件哪怔。我們先來分析一下,如果要將單鏈表1->2->3->4->5->6->7->8 變成8->7->6->5->4->3->2->1向抢,只需要先把鏈表變成1->8->7->6->5->4->3->2认境,然后在將第一個(gè)節(jié)點(diǎn)1鏈接到鏈表的尾部就行了。但是要實(shí)現(xiàn)1->8->7->6->5->4->3->2挟鸠,就需要先把將節(jié)點(diǎn)1后面的子鏈表逆序叉信。同理,要將2->3->4->5->6->7->8逆序艘希,就需要先把鏈表變成2->8->7->6->5->4->3硼身,然后將節(jié)點(diǎn)2鏈接到該鏈表的尾部就可以實(shí)現(xiàn)鉴未。直到鏈表只剩一個(gè)節(jié)點(diǎn)8。所以可以看出遞歸定義為:將第一個(gè)節(jié)點(diǎn)后面的子鏈表逆序鸠姨,然后對(duì)該子鏈表做同樣的操作铜秆。遞歸終止的條件為:遞歸下去,直到鏈表只剩一個(gè)元素為止讶迁。下面通過代碼實(shí)現(xiàn):

def RecursiveReverese(head):
    '''
    沒有頭節(jié)點(diǎn)
    '''
    #Recursive:遞歸  Reverese:逆序
    #先判斷鏈表是否只有一個(gè)元素连茧,是則返回上一層;是否為空巍糯,是則返回
    if head is None or head.next is None:
        return head
    else:
        #不為空啸驯,則遞歸逆序除第一個(gè)節(jié)點(diǎn)外的子鏈表
        newhead = RecursiveReverese(head.next)
        #前面當(dāng)鏈表只有一個(gè)元素時(shí)返回了上一層,也就是說此時(shí)有兩個(gè)元素祟峦。
        #將當(dāng)前遍歷到的節(jié)點(diǎn)鏈接到鏈表尾部
        head.next.next = head
        head.next = None
    return newhead

def Reverese(head):
    '''
    帶頭節(jié)點(diǎn)
    :param head: 帶頭節(jié)點(diǎn)鏈表
    :return: 逆序后的鏈表
    '''
    if head.next is None:
        return head
    #因?yàn)轭^節(jié)點(diǎn)沒有數(shù)據(jù)罚斗,不需要參與逆序,所以從第一個(gè)節(jié)點(diǎn)開始逆序
    newhead=RecursiveReverese(head.next)
    head.next=newhead
    return head

處理函數(shù)就是這些宅楞,下面給個(gè)全部的代碼:

#先建立節(jié)點(diǎn)對(duì)象LNode
class LNode:
    def __init__(self,arg):
        # 這是數(shù)據(jù)域data
        self.data = arg    
        # 這是節(jié)點(diǎn)的next域针姿,也就是下一個(gè)節(jié)點(diǎn)的引用
        self.next = None  
"""
方法功能:創(chuàng)建一個(gè)帶頭節(jié)點(diǎn)的單鏈表
"""
def creatLink(x):
    #  x是鏈表的長(zhǎng)度 
    i = 1
    head = LNode(None) # 先構(gòu)造單鏈表的頭節(jié)點(diǎn)
    tmp = None # 用來指向新添加的節(jié)點(diǎn)
    cur = head # 用來指向鏈表的最后一個(gè)節(jié)點(diǎn)
    while i <= x:
        tmp = LNode(i)
        cur.next = tmp
        cur = tmp
        i += 1
    return head
def RecursiveReverese(head):
    '''
    沒有頭節(jié)點(diǎn)
    '''
    #Recursive:遞歸  Reverese:逆序
    #先判斷鏈表是否只有一個(gè)元素,是則返回上一層厌衙;是否為空距淫,是則返回
    if head is None or head.next is None:
        return head
    else:
        #不為空,則遞歸逆序除第一個(gè)節(jié)點(diǎn)外的子鏈表
        newhead = RecursiveReverese(head.next)
        #前面當(dāng)鏈表只有一個(gè)元素時(shí)返回了上一層婶希,也就是說此時(shí)有兩個(gè)元素榕暇。
        #將當(dāng)前遍歷到的節(jié)點(diǎn)鏈接到鏈表尾部
        head.next.next = head
        head.next = None
    return newhead

def Reverese(head):
    '''
    帶頭節(jié)點(diǎn)
    :param head: 帶頭節(jié)點(diǎn)鏈表
    :return: 逆序后的鏈表
    '''
    if head.next is None:
        return head
    #因?yàn)轭^節(jié)點(diǎn)沒有數(shù)據(jù),不需要參與逆序喻杈,所以從第一個(gè)節(jié)點(diǎn)開始逆序
    newhead=RecursiveReverese(head.next)
    head.next=newhead
    return head

if __name__=='__main__':
    head = creatLink(8)
    cur = head.next
    #打印鏈表
    print("BeforeReversehead:")
    while cur is not None:
        print(cur.data)
        cur = cur.next
    #調(diào)用逆序函數(shù)
    head = Reverese(head)
    cur = head.next
    #打印逆序后鏈表
    print("AfterRevershead:")
    while cur is not None:
        print(cur.data)
        cur = cur.next

運(yùn)行結(jié)果如下:

程序運(yùn)行結(jié)果

大家自己寫一寫彤枢,學(xué)習(xí)效果更好喲!在我的github上也有代碼筒饰,你可以對(duì)照一下缴啡,亦可以將你的代碼發(fā)我給我、私信我龄砰,也可以關(guān)注我自己的公眾號(hào):DKider 來聯(lián)系我盟猖,我們一起看看對(duì)不對(duì),一起學(xué)習(xí)一起進(jìn)步换棚。

加油J礁洹!固蚤!

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末娘汞,一起剝皮案震驚了整個(gè)濱河市,隨后出現(xiàn)的幾起案子夕玩,更是在濱河造成了極大的恐慌你弦,老刑警劉巖惊豺,帶你破解...
    沈念sama閱讀 216,496評(píng)論 6 501
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場(chǎng)離奇詭異禽作,居然都是意外死亡尸昧,警方通過查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,407評(píng)論 3 392
  • 文/潘曉璐 我一進(jìn)店門旷偿,熙熙樓的掌柜王于貴愁眉苦臉地迎上來烹俗,“玉大人,你說我怎么就攤上這事萍程〈蓖” “怎么了?”我有些...
    開封第一講書人閱讀 162,632評(píng)論 0 353
  • 文/不壞的土叔 我叫張陵茫负,是天一觀的道長(zhǎng)蕉鸳。 經(jīng)常有香客問我,道長(zhǎng)忍法,這世上最難降的妖魔是什么潮尝? 我笑而不...
    開封第一講書人閱讀 58,180評(píng)論 1 292
  • 正文 為了忘掉前任,我火速辦了婚禮缔赠,結(jié)果婚禮上衍锚,老公的妹妹穿的比我還像新娘友题。我一直安慰自己嗤堰,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,198評(píng)論 6 388
  • 文/花漫 我一把揭開白布度宦。 她就那樣靜靜地躺著踢匣,像睡著了一般。 火紅的嫁衣襯著肌膚如雪戈抄。 梳的紋絲不亂的頭發(fā)上离唬,一...
    開封第一講書人閱讀 51,165評(píng)論 1 299
  • 那天,我揣著相機(jī)與錄音划鸽,去河邊找鬼输莺。 笑死,一個(gè)胖子當(dāng)著我的面吹牛裸诽,可吹牛的內(nèi)容都是我干的嫂用。 我是一名探鬼主播,決...
    沈念sama閱讀 40,052評(píng)論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼丈冬,長(zhǎng)吁一口氣:“原來是場(chǎng)噩夢(mèng)啊……” “哼嘱函!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起埂蕊,我...
    開封第一講書人閱讀 38,910評(píng)論 0 274
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤往弓,失蹤者是張志新(化名)和其女友劉穎疏唾,沒想到半個(gè)月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體函似,經(jīng)...
    沈念sama閱讀 45,324評(píng)論 1 310
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡槐脏,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,542評(píng)論 2 332
  • 正文 我和宋清朗相戀三年,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了撇寞。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片准给。...
    茶點(diǎn)故事閱讀 39,711評(píng)論 1 348
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡,死狀恐怖重抖,靈堂內(nèi)的尸體忽然破棺而出露氮,到底是詐尸還是另有隱情,我是刑警寧澤钟沛,帶...
    沈念sama閱讀 35,424評(píng)論 5 343
  • 正文 年R本政府宣布畔规,位于F島的核電站,受9級(jí)特大地震影響恨统,放射性物質(zhì)發(fā)生泄漏叁扫。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,017評(píng)論 3 326
  • 文/蒙蒙 一畜埋、第九天 我趴在偏房一處隱蔽的房頂上張望莫绣。 院中可真熱鬧,春花似錦悠鞍、人聲如沸对室。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,668評(píng)論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)掩宜。三九已至,卻和暖如春么翰,著一層夾襖步出監(jiān)牢的瞬間牺汤,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 32,823評(píng)論 1 269
  • 我被黑心中介騙來泰國(guó)打工浩嫌, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留檐迟,地道東北人。 一個(gè)月前我還...
    沈念sama閱讀 47,722評(píng)論 2 368
  • 正文 我出身青樓码耐,卻偏偏與公主長(zhǎng)得像追迟,于是被迫代替她去往敵國(guó)和親。 傳聞我的和親對(duì)象是個(gè)殘疾皇子伐坏,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,611評(píng)論 2 353