劍指offer25 合併兩個排序的鍊錶

2021-09-27 15:27:01 字數 3654 閱讀 1850

題目:輸入兩個遞增排序的鍊錶,合併這兩個鍊錶並使新鍊錶中的節點仍然使遞增排序的。例如:輸入下圖的鍊錶1和鍊錶2,則合併之後的公升序鍊錶如圖鍊錶3所示。

鍊錶定義如下:

思路:從兩個鍊錶的頭結點開始,比較兩個鍊錶的頭結點的值大小,值小的結點就是合併後鍊錶的頭結點,繼續合併鍊錶中剩餘的節點,在兩個鍊錶中剩下的節點依然是有序的,因此合併這兩個鍊錶的步驟和前面的步驟是一樣的,還是比較兩個頭結點的值,若其中乙個鍊錶已經全部加入到合併後的鍊錶中而另乙個鍊錶還有剩餘的節點,則將另乙個鍊錶中剩餘的節點直接加入到合併後的鍊錶中。

以題目中給的例子為例進行分析:

(1)定義兩個指標p1和p2,分別指向兩個鍊錶的頭節點,如圖1所示;

(2)鍊錶1的頭結點的值為1小於鍊錶2的頭結點的值,因此鍊錶1的頭節點是合併後鍊錶的頭節點,將p1指向鍊錶1中的下乙個節點,如圖2所示;

(3)在剩餘的節點中,鍊錶2的頭節點的值小於鍊錶1的頭節點的值,因此鍊錶2的頭節點是剩餘節點的頭節點,把這個節點和之前已經合併好的鍊錶的尾節點連線起來,將p2指向鍊錶2中的下乙個節點,如圖3所示;

(4)重複上面的步驟,直到其中乙個鍊錶全部加入到已經合併好的鍊錶中,若另乙個鍊錶還有剩餘的節點,則將另乙個鍊錶中剩餘的節點直接加入到合併後的鍊錶中。

具體**如下圖所示:

//帶頭節點的單鏈表非遞迴實現

#include #include using namespace std;

struct listnode

;void init(listnode* plisthead)

plisthead->next=null;

}static listnode* buynode()

bool inserttail(listnode *plisthead,int val)

listnode *pcur=plisthead;

while(pcur->next != null)

listnode *pnewnode=buynode();

pnewnode->value=val;

pcur->next=pnewnode;

return true;

}listnode *merge(listnode *plisthead1,listnode *plisthead2)

else if(plisthead2 == null)

plisthead1=plisthead1->next;

plisthead2=plisthead2->next;

listnode *plisthead3=new listnode();

listnode *p=plisthead3;

while(plisthead1 != null && plisthead2 != null)

else

p=p->next;

} if(plisthead1 != null)

else

return plisthead3;

}void print(listnode* plisthead)

struct listnode* pcur=plisthead->next;

while(pcur != null)

cout

listnode* pnext=pcur;

while(pcur != null)

plisthead->next=null;}

void destory(listnode* plisthead)

int main()

val=0;

for(int i=0;i<4;i++)

print(&plisthead1);

print(&plisthead2);

listnode *tmp;

tmp=merge(&plisthead1,&plisthead2);

print(tmp);

destory(tmp);

return 0;

}

執行結果如下:

//不帶頭結點的單鏈表遞迴實現

#include #include using namespace std;

typedef struct listnode

listnode,*list;

void init(list* plisthead)

*plisthead=null;

}static listnode* buynode(int val)

bool inserttail(list *plisthead,int val)

if(*plisthead == null)

list pcur=*plisthead;

while(pcur->next != null)

list pnewnode=buynode(val);

pcur->next=pnewnode;

return true;

}listnode *merge(listnode *plisthead1,listnode *plisthead2)

else if(plisthead2 == null)

listnode *pmergedhead=null;

if(plisthead1->value < plisthead2->value)

else

return pmergedhead;

}void print(listnode* plisthead)

listnode* pcur=plisthead;

while(pcur != null)

printf("\n");

}void clear(listnode* plisthead)

plisthead->next=null;}

void destory(listnode* plisthead)

int main()

val=0;

for(int i=0;i<4;i++)

print(plisthead1);

print(plisthead2);

list tmp;

tmp=merge(plisthead1,plisthead2);

print(tmp);

return 0;

}

執行結果如下:

劍指offer 25 合併兩個排序的鍊錶

輸入兩個單調遞增的鍊錶,輸出兩個鍊錶合成後的鍊錶,當然我們需要合成後的鍊錶滿足單調不減規則。1 非遞迴的方法 如果可以改變鍊錶,直接從頭結點開始依次移動比較兩個鍊錶當前值的大小,把較小的值作為當前結點的下乙個結點。注意 剛剛開始的時候不知道頭結點到底是1的還是2的,所以新建乙個額外的新節點作為輔助 ...

劍指offer 25 合併兩個排序的鍊錶

輸入兩個遞增排序的鍊錶,合併這兩個鍊錶並使新鍊錶中的節點仍然是遞增排序的。輸入 1 3 5 2 4 5 輸出 1 2 3 4 5 5 二路歸併 新建乙個頭節點pmergedhead,並設定乙個指標pcurrenthead指向pmergedhead比較phead1和phead2指標指向的值 phead...

劍指 Offer 25 合併兩個排序的鍊錶

輸入兩個遞增排序的鍊錶,合併這兩個鍊錶並使新鍊錶中的節點仍然是遞增排序的。示例1 輸入 1 2 4,1 3 4 輸出 1 1 2 3 4 4 限制 0 鍊錶長度 1000 解 原地修改 雙指標各指乙個原鍊錶,比較大小,新增較小節點至合併鍊錶,雙指標交替前進。時間複雜度o m n 空間複雜度o 1 c...