1. 合並兩個有序的單鏈表成一個有序的單鏈表
方法分為遞歸實現與非遞歸實現,兩種方法都不額外開辟 內存空間
鏈表的數據結構在本博客的單鏈表逆轉,約瑟夫環等
遞歸實現:
//遞歸實現合並兩個有序單鏈表
LinkNode* merge_list(LinkNode *pHead1, LinkNode *pHead2)
{
if(pHead1==NULL)
return pHead2;
if(pHead2==NULL)
return pHead1;
if(pHead1==NULL && pHead2==NULL)
return NULL;
LinkNode *pMergedHead=NULL;
if(pHead1->value<pHead2->value)
{
pMergedHead=pHead1;
pMergedHead->next = merge_list(pHead1->next, pHead2);
}
else
{
pMergedHead=pHead2;
pMergedHead->next=merge_list(pHead1, pHead2->next);
}
return pMergedHead;
}
//遞歸實現合並兩個有序單鏈表
LinkNode* merge_list(LinkNode *pHead1, LinkNode *pHead2)
{
if(pHead1==NULL)
return pHead2;
if(pHead2==NULL)
return pHead1;
if(pHead1==NULL && pHead2==NULL)
return NULL;
LinkNode *pMergedHead=NULL;
if(pHead1->value<pHead2->value)
{
pMergedHead=pHead1;
pMergedHead->next = merge_list(pHead1->next, pHead2);
}
else
{
pMergedHead=pHead2;
pMergedHead->next=merge_list(pHead1, pHead2->next);
}
return pMergedHead;
}
非遞歸實現:
//非遞歸實現合並兩個有序單鏈表(不額外開辟空間)
LinkNode* non_merge_list(LinkNode *pHead1, LinkNode *pHead2)
{
if(pHead1==NULL)
return pHead2;
if(pHead2==NULL)
return pHead1;
if(pHead1==NULL && pHead2==NULL)
return NULL;
LinkNode *pMergedHead = NULL;
LinkNode *q=NULL;
if(pHead1->value<pHead2->value)
{
pMergedHead=pHead1;
pHead1=pHead1->next;
}
else
{
pMergedHead=pHead2;
pHead2=pHead2->next;
}
q=pMergedHead;
while(pHead1 && pHead2)
{
if(pHead1->value<pHead2->value)
{
q->next=pHead1;
pHead1=pHead1->next;
}
else
{
q->next=pHead2;
pHead2=pHead2->next;
}
q=q->next;
}
if(pHead1)
{
while(pHead1)
{
q->next=pHead1;
q=q->next;
pHead1=pHead1->next;
}
}
if(pHead2)
{
while(pHead2)
{
q->next=pHead2;
q=q->next;
pHead2=pHead2->next;
}
}
return pMergedHead;
}
//非遞歸實現合並兩個有序單鏈表(不額外開辟空間)
LinkNode* non_merge_list(LinkNode *pHead1, LinkNode *pHead2)
{
if(pHead1==NULL)
return pHead2;
if(pHead2==NULL)
return pHead1;
if(pHead1==NULL && pHead2==NULL)
return NULL;
LinkNode *pMergedHead = NULL;
LinkNode *q=NULL;
if(pHead1->value<pHead2->value)
{
pMergedHead=pHead1;
pHead1=pHead1->next;
}
else
{
pMergedHead=pHead2;
pHead2=pHead2->next;
}
q=pMergedHead;
while(pHead1 && pHead2)
{
if(pHead1->value<pHead2->value)
{
q->next=pHead1;
pHead1=pHead1->next;
}
else
{
q->next=pHead2;
pHead2=pHead2->next;
}
q=q->next;
}
if(pHead1)
{
while(pHead1)
{
q->next=pHead1;
q=q->next;
pHead1=pHead1->next;
}
}
if(pHead2)
{
while(pHead2)
{
q->next=pHead2;
q=q->next;
pHead2=pHead2->next;
}
}
return pMergedHead;
}
2 輸出單鏈表中的中間元素(若鏈表節點個數為偶數,則輸出中間兩個的任意一個)
思路:利用兩個指針從頭節點開始遍歷,一個走一步,一個走兩步,當一次走兩步的指針走到鏈表末尾時,此時一次走一步的指針就指向鏈表的中間節點
代碼如下:
LinkNode* print_mid_node(LinkNode *pHead)
{
LinkNode *pOne = pHead, *pTwo = pHead;
while(1)
{
pOne = pOne->next;
pTwo = pTwo->next->next;
if(pTwo==NULL || pTwo->next==NULL)
return pOne;
}
}
LinkNode* print_mid_node(LinkNode *pHead)
{
LinkNode *pOne = pHead, *pTwo = pHead;
while(1)
{
pOne = pOne->next;
pTwo = pTwo->next->next;
if(pTwo==NULL || pTwo->next==NULL)
return pOne;
}
}
3 判斷單戀表是否有環
思路與第二題一樣,只是結束條件不一樣,如果當一次走一步的指針等於一次走兩步的指針時,則表示該鏈表有環
代碼如下:
bool is_circle_list(LinkNode *pHead)
{
LinkNode *pOne = pHead, *pTwo = pHead;
while(1)
{
pOne = pOne->next;
pTwo = pTwo->next->next;
if(pOne == pTwo)
return true;
if(pTwo==NULL || pTwo->next==NULL)
return false;
}
}
bool is_circle_list(LinkNode *pHead)
{
LinkNode *pOne = pHead, *pTwo = pHead;
while(1)
{
pOne = pOne->next;
pTwo = pTwo->next->next;
if(pOne == pTwo)
return true;
if(pTwo==NULL || pTwo->next==NULL)
return false;
}
}