演算法題 合併兩個有序的鍊錶

2021-06-23 01:49:51 字數 1979 閱讀 3554

題目:已知有兩個有序的單鏈表,其頭指標分別為head1和head2,實現將這兩個鍊錶合併的函式:

node* listmerge(node *head1,node *head2)

這個演算法很像我們排序演算法中的歸併排序,只能說「很像」,因為思想是一樣的,但是這個與歸併排序還是有區別的,區別如下:

1.歸併排序是針對有序陣列,而這裡是有序鍊錶;

2.歸併排序排序的時間複雜度為o(nlogn),而這裡的時間複雜度最壞情況下為o(m+n),最好的情況下為o(min)。

3.歸併排序需要重新申請空間,而這裡無需再重新申請空間,只需改變鍊錶結點的指標指向。

而這裡演算法的思想跟歸併排序是一樣的,都是對兩個待歸併的線性表分別設定1個指標,比較這兩個當前指標的大小,將小的結點加入到合併後的線性表中,並向後移動當前指標。若兩個線性表中,至少有乙個表掃瞄完,走將對應的另乙個表之間整體新增到合併後的線性表中。在這裡:鍊錶和陣列的區別在於,鍊錶只需要改變當前合併序列尾指標的位置,而陣列則要將剩下的值依次複製到歸併表的尾部

演算法的遞迴實現如下:

node *listmerge1(node *head1,node *head2)//採用遞迴的方法實現

else

return head;

}

演算法的非遞迴實現如下:

node *listmerge(node *head1,node *head2)

else

node *p=head;//p永遠指向最新合併的結點

while(p1 && p2)//如果迴圈停止,則p1或p2至少有乙個為null

else

p=p->next;

} if(p1)//如果鏈1還沒走完

else if(p2)//如果鏈2還沒走完

return head;

}

整個測試**如下:

#includeusing namespace std;

struct node

};/*建立乙個鍊錶,1->2->3->4->5->6->7*/

node* createlist1()//建立乙個有序的單鏈表1

node* createlist2()//建立乙個有序的單鏈表2

void freelist(node *head)//將鍊錶空間釋放

else }

void visitlist(node *head)//遍歷鍊錶中的元素,用遞迴的方法遍歷

else

else

node *p=head;//p永遠指向最新合併的結點

while(p1 && p2)//如果迴圈停止,則p1或p2至少有乙個為null

else

p=p->next;

} if(p1)//如果鏈1還沒走完

else if(p2)//如果鏈2還沒走完

return head;

}node *listmerge1(node *head1,node *head2)//採用遞迴的方法實現

else

return head;

}int main()

{ node *head1=createlist1();

node *head2=createlist2();

cout<

測試結果如下:

參考資料-------------《劍指offer》

演算法題 合併兩個有序的鍊錶

題目 已知有兩個有序的單鏈表,其頭指標分別為head1和head2,實現將這兩個鍊錶合併的函式 node listmerge node head1,node head2 這個演算法很像我們排序演算法中的歸併排序,只能說 很像 因為思想是一樣的,但是這個與歸併排序還是有區別的,區別如下 1.歸併排序是...

演算法題 合併兩個有序的鍊錶

題目 已知有兩個有序的單鏈表,其頭指標分別為head1和head2,實現將這兩個鍊錶合併的函式 node listmerge node head1,node head2 這個演算法很像我們排序演算法中的歸併排序,只能說 很像 因為思想是一樣的,但是這個與歸併排序還是有區別的,區別如下 1.歸併排序是...

演算法題 easy 合併兩個有序鍊錶

大學本科階段就對鍊錶比較頭疼,沒有理解透徹,做題目的時候就比較吃力,鍊錶有很多態別,單鏈表 雙鏈表 迴圈鍊錶和雙向鍊錶等,操作也有很多,插入 刪除和排序等,其實只要理解了節點的資料結構,問題就迎刃而解了。節點由資料和指標 next 構成,在對節點操作的過程中,會有乙個虛擬的指標 並不是節點中的nex...