已知鏈表的頭結點head,寫一個函數把這個鏈表逆序 ( Intel)
Node * ReverseList(Node *head) //鏈表逆序
{
if ( head == NULL || head->next == NULL ) // 否則下面的就錯了,一定要注意一些特定條件的判斷,邊界問題狠重要,軟體開發要注意對異常分支的處理
// 三個指標的方式結構比較清晰
Node *p1 = head;
Node *p2 = p1->next;
Node *p3 = p2->next;
p1->next = NULL;
while ( p3 != NULL )
{
p2->next = p1; // p2->next為p3,已經儲存過了
//p1、p2、p3都向前移動一個
p1 = p2;
p2 = p3;
p3 = p3->next;
}
p2->next = p1; //最末端節點掛在鏈上
head = p2;
return head;
}
已知兩個鏈表head1 和head2 各自有序升序排列,請把它們合并成一個鏈表依然有序。(保留所有結點,即便大小相同)
Node * Merge(Node *head1 , Node *head2)
{
if ( head1 == NULL)
return head2;
if ( head2 == NULL)
return head1;
// 良好的習慣,指標要初始化為NULL
Node *head = NULL;
Node *p1 = NULL;
Node *p2 = NULL;
// 從小到大,獲得前端節點
if ( head1->data =< head2->data )
{
head = head1;
p1 = head1->next; // 注意更新的不一樣
p2 = head2;
}
else
{
head = head2;
p2 = head2->next;
p1 = head1;
}
Node *pcurrent = head;
while ( p1 != NULL && p2 != NULL)
{
if ( p1->data <= p2->data )
{
pcurrent->next = p1; // 掛接新節點
pcurrent = p1; //更新當前最後一個節點
p1 = p1->next; //更新下一個待比較節點
}
else
{
pcurrent->next = p2;
pcurrent = p2;
p2 = p2->next;
}
}
if ( p1 != NULL ) //掛接剩餘部分
pcurrent->next = p1;
if ( p2 != NULL )
pcurrent->next = p2;
return head;
}
已知兩個鏈表head1 和head2 各自升序排列,請把它們合并成一個鏈表依然有序,這次要求用遞迴方法進行。 (Autodesk)
遞迴版本實際上很容易從上面一個版本改動而得來,主要是注意退出的條件和跌代的條件。
Node * MergeRecursive(Node *head1 , Node *head2)
{//允出準則是某鏈結束
if ( head1 == NULL )
return head2;
if ( head2 == NULL)
return head1;
Node *head = NULL;
if ( head1->data < head2->data )
{
head = head1;
head->next = MergeRecursive(head1->next,head2);
}
else
{
head = head2;
head->next = MergeRecursive(head1,head2->next);
}
return head;
}