三个链表面试题目综合:找到链表倒数K个节点、链表逆转、合并两个链表。
#include <iostream>
using namespace std;
typedef struct linklist{
linklist *link;
int val;
}*listPoint;
//按节点值升序插入链表
void insertNode(listPoint &head,int val)
{
linklist *pre,*current;
pre=NULL;
current=head;
while (current!=NULL&&val>current->val)
{
pre=current;
current=current->link;
}
linklist *newNode=new linklist;
if (newNode==NULL)
{
cout<<"memory errors \n";
}
newNode->val=val;
newNode->link=current;
if (pre==NULL)
{
head=newNode;
}
else
pre->link=newNode;
}
//这个函数最重要是注意边界条件,防止程序崩溃!
linklist *FindKthFromNail(linklist *head,int k)
{
if (head==NULL||k<=0)
{
cout<<" 链表不符合条件 \n";
return NULL;
}
linklist *ahead,*behind;
ahead=behind=head;
int i;
/*
最终情况是需要让ahead指向链表尾节点,然后此时behind则指向倒数K个节点
ahead 与behind 相差K-1个距离。如果ahead 提前K-1走碰到NULL ,意味着链表节点数不够K个返回。
*/
for (i=0;i<k-1;i++)
{
if (ahead->link!=NULL)
{
ahead=ahead->link;
}
else
{
return NULL;
}
}
while (ahead->link!=NULL)
{
ahead=ahead->link;
behind=behind->link;
}
return behind;
}
//实现链表反转
linklist * reverseList(linklist *head)
{
linklist *pre=NULL,*current,*next;
current=head;
for (;current!=NULL;current=next)
{
next=current->link;
current->link=pre;
pre=current;
}
return pre;
}
void printList(linklist *head)
{
if (head==NULL)
{
cout<<"empty linklist \n";
}
while (head!=NULL)
{
cout<<head->val<<" ";
head=head->link;
}
cout<<endl;
}
//合并两个升序链表,返回头结点位置。递归可以很简单实习功能
linklist * mergeLinklist(linklist *head1,linklist *head2)
{
/*
合并时特别考虑代码健壮性,如果链表为NULL情况处理
*/
if (head1==NULL)
{
return head2;
}
else if (head2==NULL)
{
return head1;
}
linklist *Pmerge=NULL;
if (head1->val<head2->val)
{
Pmerge=head1;
Pmerge->link=mergeLinklist(head1->link,head2);
}
else
{
Pmerge=head2;
Pmerge->link=mergeLinklist(head1,head2->link);
}
return Pmerge;
}
int main()
{
int a[]={1,2,5,8,4,3};
int b[]={6,7,9,10,12,11,14,13};
int i;
linklist *head1=NULL;
linklist *head2=NULL;
for (i=0;i<6;i++)
{
insertNode(head1,a[i]);
}
for (i=0;i<8;i++)
{
insertNode(head2,b[i]);
}
printList(mergeLinklist(head1,head2));
}
题目及算法思想来源于剑指offer,感谢作者对代码健壮性的讲解。