单向链表的逆置问题
單鏈逆置
常見的面試題,主要考查邏輯能力。
使用歸納法來解這道題。核心是下面的reverse()函數,其主要思路如下:
把一個鏈表分為三個部分:
- 前面是逆置完成(prev指針),
- 當前指針指向的位置(curr指針),
- 后面未處理的部分(next指針)。
需要注意的地方
先想好循環體如何實現
snode* next = curr->next;//后面的指針
curr->next= prev;//逆置
prev = curr;//指針往后挪
curr = next;//指針往后挪
再回過頭來想curr指針和prev指針的初值
snode* prev = NULL;//想一想為什么是NULL,而不是啞結點header
snode* curr = header->next;//第一個真實的結點
最后勿忘把啞結點鏈接上
header->next=prev;
單向鏈表逆序reverse()函數
void reverse(snode* header) {snode* prev = NULL;snode* curr = header->next;while (curr != NULL){snode* next = curr->next;//后面的指針curr->next= prev;//逆置prev = curr;//指針往后挪curr = next;//指針往后挪}header->next = prev;//很容易忘記這一步!}鏈表遍歷打印traverse()函數:
//遍歷鏈表traverse void traverse(snode * header) {for (snode* p = header->next; p != NULL; p = p->next)cout << p->data << " ";cout << endl; }完整代碼:
// reverse_front_list.cpp : 此文件包含 "main" 函數。程序執行將在此處開始并結束。#include "pch.h" #include<iostream> #include<vector>using namespace std;//結點結構體 struct snode {int data;snode* next; };//遍歷鏈表traverse void traverse(snode * header) {for (snode* p = header->next; p != NULL; p = p->next)cout << p->data << " ";cout << endl; }//逆序鏈表 void reverse(snode* header) {snode* prev = NULL;//snode* curr = header->next;while (curr != NULL){snode* next = curr->next;//后面的指針curr->next= prev;//逆置prev = curr;//指針往后挪curr = next;//指針往后挪}header->next = prev;//很容易忘記這一步!}int main() {vector<snode> V = { {}, {1, NULL}, {2, NULL}, {3, NULL} };//向量鏈接成鏈表for (size_t i = 0; i+1 < V.size(); ++i){V[i].next = &V[i+ 1];}cout << "鏈表逆序之前" << endl;traverse(&V[0]);//遍歷輸出reverse(&V[0]);//逆置cout << "鏈表逆序之后" << endl;traverse(&V[0]);//遍歷輸出return 0; }程序結果:
回答問題:
現在來回答為什么prev指針初值為NULL,而不是header。
第一次使用prev指針是在哪里?在循環體中。
我們從具體的分析中更好地可以得出結論。
假設初始第一個結點數值為1,即Curr->data=1,逆置之后1就是最后一個結點,它應該指向空指針,也就是curr->next=NULL.也就是這里的prev的初值應該NULL,而不是header,因為這是單向鏈表。
希望對你有幫助。
《新程序員》:云原生和全面數字化實踐50位技術專家共同創作,文字、視頻、音頻交互閱讀總結
- 上一篇: 怎么报保险
- 下一篇: 帮别人贷款买车有什么风险