您的位置:首页 > 编程语言 > C语言/C++

C/C++面试之算法系列--典型的几个链表操作-逆序和重排

2008-10-11 01:42 711 查看
已知链表的头结点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;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: 
相关文章推荐