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;
}
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;
}
相关文章推荐
- C/C++面试之算法系列--几个典型的内存拷贝及字符串函数实现
- 典型的几个链表操作-逆序和重排
- 典型的几个链表操作-逆序和重排
- 典型的几个链表操作-逆序和重排
- 转:C/C++面试之算法系列--怎样快速检测出一个巨大的单链表中是否具备死链及其位置
- C/C++面试之算法系列--几个最大子字符串的算法题
- C/C++面试之算法系列--一次遍历找链表倒数第n个节点
- C/C++面试之算法系列--怎样快速检测出一个巨大的单链表中是否具备死链及其位置
- C/C++面试之算法系列--怎样快速检测出一个巨大的单链表中是否具备死链及其位置
- C/C++链表操作(面试)
- 数据结构入门学习系列-5(链表的基本操作算法)
- 【面试算法系列】逆序输出一个单链表 - C语言实现
- C/C++面试之算法系列--如何利用数学思想解1/2/5组合问题
- C++使用递归函数和栈操作逆序一个栈的算法示例
- 面试高频题:单链表的逆置操作/链表逆序
- 面试算法之链表操作集锦
- 【数据结构】用C++实现双循环链表的各种操作(包括头删,尾删,插入,逆序,摧毁,清空等等)
- C/C++面试之算法系列--如何实现用更少的空间表示英文字母(a ~ z)构成char A[n]字符串
- 【数据结构】用C++实现单循环链表的各种操作(包括头删,尾删,插入,逆序,摧毁,清空等等)
- 常用于面试的链表操作算法