链表是面试中常见的题目之一。下面列出常见的链表面试题。
本随笔主要针对两链表求并,求交。
1)【链表反向按序求并】两个按递增次序排列的单链表,编写算法合并,按递减次序排列,并要求利用原来两个单链表的结点存放新的链表。
LinkList Union(LinkList la,lb)
{
pa=la->next;
pb=lb->next;// pa,pb是工作指针
la->next=null;// la为结果链表的头指针
while(la&&lb)
{
if(pa->data<=pb->data)
{
r=pa->next;// 将pa的后继暂存于r
pa->next=la->next;// 将pa的结果存于结果表中,同时逆置
la->next=pa;
pa=r;// 恢复pa为当前待比较结点
}
else
{
r=pb->next;// 将pa的后继暂存于r
pb->next=la->next;// 将pb的结果存于结果表中,同时逆置
la->next=pb;
pb=r;// 恢复pb为当前待比较结点
}
if(pa) pb=pa;// 避免对pa再写如下的while语句
while(pb!=null)
{
r=pb->next;
pb->next=la->next;
la->next=pb;
pb=r;
}
}
}
2)两链表递增有序,合并后依然有序,但是要求不带重复元素
#include "stdafx.h"
#include<iostream>
using namespace std;
typedef struct node
{
int data;
struct node *next;
}Listnode,*LinkList;
int _tmain(int argc, _TCHAR* argv[])
{
return 0;
}
void Merge(LinkList &La,LinkList &Lb,LinkList &Lc)
{
LinkList pa,pb,pc,u;
pa=La->next,pb=Lb->next;
Lc=pc=La;
while(pa&&pb)
{
if(pa->data<pb->data)
{
pc->next=pa;
pc=pa;
pa=pa->next;
}
else if(pa->data>pb->data)
{
pc->next=pb;
pc=pb;
pb=pb->next;
}
else //关键步,处理相等的元素
{
pc->next=pb;
pc=pb;
pb=pb->next;
u=pa;
pa=pa->next;
free(u);
}
if(pa)pc->next=pa;else pc->next=pb;
free(Lb);
}
}
3)两个带头结点的链表从小到大排序,求两个链表的交集,要求依旧从小到大排序,没有重复元素。
#include "stdafx.h"
#include<iostream>
using namespace std;
typedef struct node
{
int data;
struct node *next;
}Listnode,*LinkList;
int _tmain(int argc, _TCHAR* argv[])
{
return 0;
}
void Merge(LinkList &La,LinkList &Lb,LinkList &Lc)
{
LinkList pa,pb,pc,u;
pa=La->next,pb=Lb->next;
Lc=pc=La;
while(pa&&pb)
{
if(pa->data<pb->data)
{
u=pa;
pa=pa->next;
free(u);
}
else if(pa->data>pb->data)
{
pb=pb->next;
}
else
{
if(pc==La) //处理第一个相等的元素
{
pc->next=pa;pc=pa;pa=pa->next;
}
else if(pc->data==pa->data) //重复元素不进入La表
{
u=pa;
pa=pa->next;free(u);
}
else //交集元素并入结果表
{
pc->next=pa;pc=pa;pa=pa->next;
}
}
while(pa) //删除La表剩余元素
{
u=pa;pa=pa->next;free(u);
}
free(Lb);
}
}