c++ 如何合并兩個有序鏈表
1.題目要求
這是一道求職面試時經(jīng)常要求手寫或者機(jī)試的經(jīng)典題目。
已知兩個鏈表head1和head2各自有序,請把它們合并成一個鏈表依然有序。結(jié)果鏈表要包含head1和head2的所有節(jié)點(diǎn),即使節(jié)點(diǎn)值相同。
注意:不能開辟新空間來存儲合并后的鏈表。如果第一次做該題,很容易會想到使用新鏈表來存儲合并后的有序鏈表。雖然可以如此實(shí)現(xiàn),但是不符合常規(guī)解法和面試官的要求。
2.非遞歸實(shí)現(xiàn)
算法過程:
輸入:兩個有序的單鏈表head1與head2;
輸出:合并后的有序單鏈表mergeHead;
算法描述:
(1)如果head1或head2為空鏈表,則直接返回另外一個鏈表;
(2)選擇head1與head2鏈表當(dāng)前節(jié)點(diǎn)值較小的節(jié)點(diǎn),掛接到后并后的鏈表mergeHead;
(3)重復(fù)步驟2,直到鏈表head1或者h(yuǎn)ead2遍歷完成,未遍歷完的鏈表,直接掛接到mergeHead的尾節(jié)點(diǎn)。
具體實(shí)現(xiàn)如下:
#include <sstream>
#include <iostream>
using namespace std;
struct ListNode
{
int value;
ListNode* next;
ListNode() {value=0;next=NULL;}
ListNode(int value,ListNode* next = NULL):value(value),next(next){}
};
//@brief:非遞歸實(shí)現(xiàn)兩個有序單鏈表
//@注意:兩個鏈表需要從小到大順序排列
ListNode* mergeOrderedLinkedList(ListNode* head1,ListNode* head2)
{
if (head1 == NULL)
{
return head2;
}
else if(head2 == NULL)
{
return head1;
}
ListNode* mergeHead = NULL;
if (head1->value<head2->value)
{
mergeHead=head1;
head1=head1->next;
}
else
{
mergeHead = head2;
head2 = head2->next;
}
ListNode* tmpNode = mergeHead;
while(head1&&head2)
{
if(head1->value<head2->value)
{
mergeHead->next = head1;
head1 = head1->next;
}
else
{
mergeHead->next = head2;
head2 = head2->next;
}
mergeHead = mergeHead->next;
}
if (head1)
{
mergeHead->next = head1;
}
if (head2)
{
mergeHead->next = head2;
}
return tmpNode;
}
//打印鏈表
void printLinkedList(ListNode* head)
{
while(head)
{
cout<<head->value<<" ";
head=head->next;
}
cout<<endl;
}
int main(int argc,char* argv[])
{
ListNode* head1=NULL,*curList1=NULL,*head2=NULL,*curList2=NULL;
string strIn;
int value;
cout<<"創(chuàng)建鏈表1,從小到大順序輸入鏈表1:"<<endl;
getline(cin,strIn);
stringstream ss(strIn);
cout<<"ss0 strIn:"<<ss.str()<<endl;
while(ss>>value) //從string中按照空格讀取int
{
ListNode* newNode1=new ListNode;
newNode1->value=value;
if(head1==NULL && curList1==NULL)
{
head1=newNode1;
curList1=newNode1;
}
else
{
curList1->next=newNode1;
curList1=curList1->next;
}
}
cout<<"創(chuàng)建鏈表2,從小到大順序輸入鏈表2:"<<endl;
getline(cin,strIn);
ss.clear(); //清空狀態(tài)
ss.str(""); //清空內(nèi)容
ss<<strIn; //重新輸出至string
cout<<"ss1 strIn:"<<ss.str()<<endl;
while(ss>>value) //從string中按照空格讀取int
{
ListNode* newNode2=new ListNode;
newNode2->value=value;
if(head2==NULL && curList2==NULL)
{
head2=newNode2;
curList2=newNode2;
}
else
{
curList2->next=newNode2;
curList2=curList2->next;
}
}
//合并兩個有序鏈表
ListNode* mergeHead=mergeOrderedLinkedList(head1,head2);
//打印鏈表
cout<<"合并后鏈表:"<<endl;
printLinkedList(mergeHead);
}
運(yùn)行程序,輸出結(jié)果:
從小到大順序輸入鏈表1:
1 2 3 5
ss0 strIn:1 2 3 5
從小到大順序輸入鏈表2:
3 4 5 6 7 8
ss1 strIn:3 4 5 6 7 8
合并后鏈表:
1 2 3 3 4 5 5 6 7 8
3.遞歸實(shí)現(xiàn)
從上面合并兩個有序鏈表的步驟中可以看出,每次合并的步驟(2)都是一樣的,由此我們想到了遞歸。具體實(shí)現(xiàn)如下:
//@brief:遞歸實(shí)現(xiàn)兩個有序單鏈表
//@注意:兩個鏈表需要從小到大順序排列
ListNode* mergeOrderedLinkedListRecursion(ListNode* head1,ListNode* head2)
{
if(head1 == NULL)
{
return head2;
}
else if(head2 == NULL)
{
return head1;
}
ListNode* mergeHead = NULL;
if(head1->value<head2->value)
{
mergeHead=head1;
mergeHead->next=mergeOrderedLinkedListRecursion(head1->next,head2);
}
else
{
mergeHead=head2;
mergeHead->next=mergeOrderedLinkedListRecursion(head1,head2->next);
}
return mergeHead;
}
以上就是c++ 如何合并兩個有序鏈表的詳細(xì)內(nèi)容,更多關(guān)于c++ 合并兩個有序鏈表的資料請關(guān)注腳本之家其它相關(guān)文章!
相關(guān)文章
json error: Use of overloaded operator [] is ambiguous錯誤的解決方
今天小編就為大家分享一篇關(guān)于json error: Use of overloaded operator [] is ambiguous錯誤的解決方法,小編覺得內(nèi)容挺不錯的,現(xiàn)在分享給大家,具有很好的參考價值,需要的朋友一起跟隨小編來看看吧2019-04-04
c++ 內(nèi)聯(lián)函數(shù)和普通函數(shù)的區(qū)別
內(nèi)聯(lián)函數(shù)是c++為了提高程序的運(yùn)行速度做的改進(jìn),那么內(nèi)聯(lián)函數(shù)和普通函數(shù)的區(qū)別是什么,本文就來詳細(xì)的介紹一下,感興趣的朋友可以了解一下2021-05-05
Qt5 串口類QSerialPort的實(shí)現(xiàn)
在Qt5以上提供了QtSerialPort模塊,方便編程人員快速的開發(fā)應(yīng)用串口的應(yīng)用程序。本文主要介紹了Qt5 串口類QSerialPort的實(shí)現(xiàn),,感興趣的可以了解一下2022-05-05

