C++面試寶典第4題:合并鏈表

題目

????????有一個鏈表,其節點聲明如下:

struct TNode
{int nData;struct TNode *pNext;TNode(int x) : nData(x), pNext(NULL) {}
};

????????現給定兩個按升序排列的單鏈表pA和pB,請編寫一個函數,實現這兩個單鏈表的合并。合并后,仍然按升序進行排列。比如:單鏈表pA為1->3->5->6->8,單鏈表pB為2->3->7,則合并后返回的鏈表為1->2->3->3->5->6->7->8。函數的聲明如下:

??????????TNode *MergeList(TNode *pA, TNode *pB);

解析

????????這道題主要考察應聘者對鏈表等數據結構的理解能力,在面試中比較常見。一般有兩種解法:一種是使用遞歸函數來實現,另一種是使用鏈表遍歷來實現。

????????先來看第一種解法,使用遞歸函數來實現。當鏈表pA為NULL時,直接返回鏈表pB即可。當鏈表pB為NULL時,直接返回鏈表pA即可。當鏈表pA和pB均不為NULL時,則比較鏈表首部的元素,若pA->nData小于pB->nData,則返回pA,并讓pA->pNext指向遞歸函數MergeList(pA->pNext, pB)的返回值。下面,我們給出了這道題的示例代碼。

#include<iostream>
using namespace std;struct TNode
{int nData;struct TNode *pNext;TNode(int x) : nData(x), pNext(NULL) {}
};// 插入新節點到鏈表尾部
TNode *AppendNode(TNode *pTail, int nData)
{  TNode *pNodeNew = new TNode(nData);pTail->pNext = pNodeNew;return pNodeNew;
}// 打印鏈表
void PrintList(TNode *pNode)
{while (pNode != NULL){cout << pNode->nData;pNode = pNode->pNext;if (pNode != NULL){cout << "->";}else{cout << endl;}}
}// 合并兩個鏈表
TNode *MergeList(TNode *pA, TNode *pB)
{  if (pA == NULL){return pB;}if (pB == NULL){return pA;}if (pA->nData < pB->nData){pA->pNext = MergeList(pA->pNext, pB);return pA;}else{pB->pNext = MergeList(pA, pB->pNext);return pB;}
}  int main()
{TNode *pA = new TNode(1);TNode *pTail = AppendNode(pA, 3);pTail = AppendNode(pTail, 5);pTail = AppendNode(pTail, 6);pTail = AppendNode(pTail, 8);// 輸出:1->3->5->6->8PrintList(pA);TNode *pB = new TNode(2);pTail = AppendNode(pB, 3);pTail = AppendNode(pTail, 7);// 輸出:2->3->7PrintList(pB);TNode *pResult = MergeList(pA, pB);// 輸出:1->2->3->3->5->6->7->8PrintList(pResult);return 0;
}

????????當然,遞歸函數也有其缺點:當鏈表中的元素較多,遞歸的層級較多時,可能會導致堆棧溢出。

????????接下來,我們來看第二種解法,使用鏈表遍歷來實現。首先,當鏈表pA和pB其中一個為NULL時,直接返回另一個鏈表即可。接下來,我們創建了一個新的臨時節點,作為新鏈表的頭和尾,并遍歷鏈表pA和pB。在遍歷過程中,如果pA->nData小于pB->nData,則將pA作為新鏈表尾部的下一個節點,并遍歷新鏈表尾部和pA的下一個節點;如果pA->nData不小于pB->nData,則將pB作為新鏈表尾部的下一個節點,并遍歷新鏈表尾部和pB的下一個節點。循環遍歷完成后,由于鏈表pA和pB不一樣長,因此,需要檢查鏈表pA和pB是否為NULL。若不為NULL,則將對應鏈表放到新鏈表尾部。最后,我們返回了新建節點的下一個節點作為合并后的鏈表首節點,并刪除了新建的臨時節點。具體實現,可參考如下的示例代碼。

#include<iostream>
using namespace std;struct TNode
{int nData;struct TNode *pNext;TNode(int x) : nData(x), pNext(NULL) {}
};// 插入新節點到鏈表尾部
TNode *AppendNode(TNode *pTail, int nData)
{  TNode *pNodeNew = new TNode(nData);pTail->pNext = pNodeNew;return pNodeNew;
}// 打印鏈表
void PrintList(TNode *pNode)
{while (pNode != NULL){cout << pNode->nData;pNode = pNode->pNext;if (pNode != NULL){cout << "->";}else{cout << endl;}}
}// 合并兩個鏈表
TNode *MergeList(TNode *pA, TNode *pB)
{if (pA == NULL){return pB;}if (pB == NULL){return pA;}TNode *pResult = new TNode(-1);TNode *pTail = pResult;while (pA && pB){if (pA->nData < pB->nData){pTail->pNext = pA;pTail = pTail->pNext;pA = pA->pNext;} else{pTail->pNext = pB;pTail = pTail->pNext;pB = pB->pNext;}}if (pA){pTail->pNext = pA;}if (pB){pTail->pNext = pB;}TNode *pTemp = pResult;pResult = pResult->pNext;delete pTemp;return pResult;
}int main()
{TNode *pA = new TNode(1);TNode *pTail = AppendNode(pA, 3);pTail = AppendNode(pTail, 5);pTail = AppendNode(pTail, 6);pTail = AppendNode(pTail, 8);// 輸出:1->3->5->6->8PrintList(pA);TNode *pB = new TNode(2);pTail = AppendNode(pB, 3);pTail = AppendNode(pTail, 7);// 輸出:2->3->7PrintList(pB);TNode *pResult = MergeList(pA, pB);// 輸出:1->2->3->3->5->6->7->8PrintList(pResult);return 0;
}

總結

????????鏈表是一種常見的數據結構,它通過指針鏈接一系列的節點。通過這道題,我們學習了鏈表的數據結構,以及鏈表合并的操作。

????????另外,我們還為你留了一些課后的拓展作業,快來試一試吧!

????????1、給定一個單向鏈表,判斷鏈表中是否有環。

????????2、給定一個單向鏈表的頭節點,寫一個函數將其反轉。

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

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

相關文章

scheduleatfixedrate詳解

scheduleatfixedrate詳解 大家好&#xff0c;我是免費搭建查券返利機器人賺傭金就用微賺淘客系統3.0的小編&#xff0c;也是冬天不穿秋褲&#xff0c;天冷也要風度的程序猿&#xff01;在Java開發中&#xff0c;我們常常需要執行定時任務&#xff0c;并且需要保證任務按照一定…

使用Java實現基數排序算法

文章目錄 基數排序算法 基數排序算法 &#xff08;1&#xff09;基本思想&#xff1a;將整數按位數切割成不同的數字&#xff0c;然后按每個位數分別比較。 &#xff08;2&#xff09;排序過程&#xff1a;將所有待比較數值&#xff08;正整數&#xff09;統一為同樣的數位長…

Vuex快速上手

一、Vuex 概述 目標&#xff1a;明確Vuex是什么&#xff0c;應用場景以及優勢 1.是什么 Vuex 是一個 Vue 的 狀態管理工具&#xff0c;狀態就是數據。 大白話&#xff1a;Vuex 是一個插件&#xff0c;可以幫我們管理 Vue 通用的數據 (多組件共享的數據)。例如&#xff1a;購…

VSCode SSH登錄服務器 提示XHR failed

設置->搜索“代理” 把圖中的√去掉 重啟 即可

OVS主線流程

OVS是open virtual switch的簡稱&#xff0c;是現在廣泛使用的軟件實現的虛擬網絡交換機。 各大云廠商普遍使用OVS來實現自身的虛擬網絡&#xff0c;各廠商會根據自身需要加以修改使之符合自身需求&#xff0c;DPU中也使用OVS來實現流表的offload。OVS中的流表基于多級結構&am…

變相增大BatchSize——梯度累積

常規訓練方式 for x,y in train_loader:pred model(x)loss criterion(pred, label)# 反向傳播loss.backward()# 根據新的梯度更新網絡參數optimizer.step()# 清空以往梯度&#xff0c;通過下面反向傳播重新計算梯度optimizer.zero_grad() pytorch每次forward完都會得到一個…

tidb安裝 centos7單機集群

安裝 [rootlocalhost ~]# curl --proto https --tlsv1.2 -sSf https://tiup-mirrors.pingcap.com/install.sh | sh [rootlocalhost ~]# source .bash_profile [rootlocalhost ~]# which tiup [rootlocalhost ~]# tiup playground v6.1.0 --db 2 --pd 3 --kv 3 --host 192.168.1…

按這個套路寫的年底工作總結,運維人能少背多少鍋?

在職場中&#xff0c;年終工作總結是一項重要的任務&#xff0c;不僅有助于回顧過去一年的工作成果&#xff0c;也為未來設定新的目標提供了參考。在進行年終工作總結的過程中&#xff0c;合理的工作匯報是至關重要的一環。 一、匯報需要堅守的4個法則 01.線索必須單一 觀點&am…

js實現元素可拖拽方法

業務需要&#xff1a;Vueelement plus實現對彈框進行拖拽&#xff0c;并可拖拽到顯示頁面的外面&#xff0c;而element提供的拖拽只能在當前頁面不可超出。所以手寫了拖拽方法。 實現效果 對元素進行拖拽 拖拽方法 function dragElement(ele) {ele.addEventListener("mous…

SQL自學通之函數 :對數據的進一步處理

目錄 一、目標 二、匯總函數 COUNT SUM AVG MAX MIN VARIANCE STDDEV 三、日期/時間函數 ADD_MONTHS LAST_DAY MONTHS_BETWEEN NEW_TIME NEXT_DAY SYSDATE 四、數學函數 ABS CEIL 和FLOOR COS、 COSH 、SIN 、SINH、 TAN、 TANH EXP LN and LOG MOD POW…

【SpringBoot教程】SpringBoot 實現前后端分離的跨域訪問(Nginx)

作者簡介&#xff1a;大家好&#xff0c;我是擼代碼的羊駝&#xff0c;前阿里巴巴架構師&#xff0c;現某互聯網公司CTO 聯系v&#xff1a;sulny_ann&#xff08;17362204968&#xff09;&#xff0c;加我進群&#xff0c;大家一起學習&#xff0c;一起進步&#xff0c;一起對抗…

Mybatis之核心配置文件詳解、默認類型別名、Mybatis獲取參數值的兩種方式

學習的最大理由是想擺脫平庸&#xff0c;早一天就多一份人生的精彩&#xff1b;遲一天就多一天平庸的困擾。各位小伙伴&#xff0c;如果您&#xff1a; 想系統/深入學習某技術知識點… 一個人摸索學習很難堅持&#xff0c;想組團高效學習… 想寫博客但無從下手&#xff0c;急需…

arm-none-eabi-gcc not find

解決辦法&#xff1a;安裝&#xff1a;gcc-arm-none-eabi sudo apt install gcc-arm-none-eabi; 如果上邊解決問題了就不用管了&#xff0c;如果解決不了&#xff0c;加上下面這句試試運氣&#xff1a; $ sudo apt-get install lsb-core看吧方正我是運氣還不錯&#xff0c;感…

leetcode周賽375 - 12 - 10

比賽地址 : 競賽 - 力扣 (LeetCode) t1 : 直接暴力即可 class Solution { public:int countTestedDevices(vector<int>& b) {int n b.size();int ans 0;for(int i0;i<n;i){if(b[i]>0){ans ;for(int ji1;j<n;j){b[j] max(b[j]-1,0);}}}return ans;} };…

SSL 數字證書的一些細節

參考&#xff1a;TLS/SSL 協議詳解(6) SSL 數字證書的一些細節1 證書驗證 地址&#xff1a;https://wonderful.blog.csdn.net/article/details/77867063 參考&#xff1a;TLS/SSL協議詳解 (7) SSL 數字證書的一些細節2 地址&#xff1a;https://wonderful.blog.csdn.net/articl…

Python學習筆記-類

1 定義類 類是函數的集合&#xff0c;class來定義類 pass并沒有實際含義&#xff0c;只是為了代碼能執行通過&#xff0c;不報錯而已&#xff0c;相當于在代碼種占一個位置&#xff0c;后續完善 類是對象的加工廠 2.創建對象 carCar()即是創建對象的過程 3、類的成員 3.1 實例…

福德植保無人機:綠色農業的新篇章

今天&#xff0c;我們榮幸地向您介紹福德植保無人機&#xff0c;一種改變傳統農業種植方式&#xff0c;引領綠色農業的新科技產品。福德植保無人機以其高效、環保、安全的特點&#xff0c;正逐漸成為植保行業的新寵。福德植保無人機是一種搭載了高性能發動機和精確噴灑系統的飛…

代碼隨想錄算法訓練營第四十六天 _ 動態規劃_背包問題總結。

學習目標&#xff1a; 動態規劃五部曲&#xff1a; ① 確定dp[i]的含義 ② 求遞推公式 ③ dp數組如何初始化 ④ 確定遍歷順序 ⑤ 打印遞歸數組 ---- 調試 引用自代碼隨想錄&#xff01; 本文大多數內容引用自代碼隨想錄 60天訓練營打卡計劃&#xff01; 學習內容&#xff1a; …

POJ - 2528 Mayor‘s posters

本題注意離散化的時候可能會出現區間串聯情況&#xff0c;比如 [1,10] [5,10] [1,4] 和 [1,10] [6,10] [1,4] 直接離散化的話兩者一樣&#xff0c;但是實際上是不一樣的 解決辦法是你在相鄰的差不是1的數對中再插一個數就好了 離線區間染色 查詢根節點 #include<iostrea…

ASPICE-汽車軟件開發能力評級

Automotive SPICE&#xff08;簡稱A-SPICE 或 ASPICE&#xff09;&#xff0c;全稱是“Automotive Software Process Improvement and Capacity dEtermination”&#xff0c;即“汽車軟件過程改進及能力評定”模型框架。 常被用于評估一家汽車軟件供應商的軟件開發能力&#x…