c++ 如何合併兩個有序連結串列
阿新 • • 發佈:2020-08-13
1.題目要求
這是一道求職面試時經常要求手寫或者機試的經典題目。
已知兩個連結串列head1和head2各自有序,請把它們合併成一個連結串列依然有序。結果連結串列要包含head1和head2的所有節點,即使節點值相同。
注意:不能開闢新空間來儲存合併後的連結串列。如果第一次做該題,很容易會想到使用新連結串列來儲存合併後的有序連結串列。雖然可以如此實現,但是不符合常規解法和麵試官的要求。
2.非遞迴實現
演算法過程:
輸入:兩個有序的單鏈表head1與head2;
輸出:合併後的有序單鏈表mergeHead;
演算法描述:
(1)如果head1或head2為空連結串列,則直接返回另外一個連結串列;
(3)重複步驟2,直到連結串列head1或者head2遍歷完成,未遍歷完的連結串列,直接掛接到mergeHead的尾節點。
具體實現如下:
#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:非遞迴實現兩個有序單鏈表 //@注意:兩個連結串列需要從小到大順序排列 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<<"建立連結串列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<<"建立連結串列2,從小到大順序輸入連結串列2:"<<endl; getline(cin,strIn); ss.clear(); //清空狀態 ss.str(""); //清空內容 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); }
執行程式,輸出結果:
從小到大順序輸入連結串列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.遞迴實現
從上面合併兩個有序連結串列的步驟中可以看出,每次合併的步驟(2)都是一樣的,由此我們想到了遞迴。具體實現如下:
//@brief:遞迴實現兩個有序單鏈表 //@注意:兩個連結串列需要從小到大順序排列 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++ 如何合併兩個有序連結串列的詳細內容,更多關於c++ 合併兩個有序連結串列的資料請關注我們其它相關文章!