二、链表
10、两个递增有序单链表,设计算法生成一个非递减有序的链表。
LinkList MergeList(LinkList &lista,LinkList &listb){
LinkList listc;
LNode *pa,*pb,*pc;
pa=lista;
pb=listb;
//比较第一个结点的大小
if(lista->data<=listb->data){
listc=lista;
pc=listc;
pa=pa->next;
}
else
{
listc=listb;
pc=listc;
pb=pb->next;
}
//之后结点的比较
while(pa!= NULL && pb!= NULL){
if(pa->data <= pb->data){
pc->next=pa;
pc=pa;
pa=pa->next;
}
else
{
pc->next=pb;
pc=pb;
pb=pb->next;
}
//若其中一个表为空了
pc->next=(pa != NULL) ? pa:pb;
return listc;
}
11、两个递增有序单链表,设计算法生成一个非递增有序的链表。
与上题类似,但是使用头插法
LinkList MergeList(LinkList &lista,LinkList &listb){
LinkList listc;
LNode *pa,*pb,*pc,*q;
pa=lista;
pb=listb;
if(lista->data<=listb->data){
listc=lista;
pc=listc;
pa=pa->next;
}
else
{
listc=listb;
pc=listc;
pb=pb->next;
}
//之后结点的比较
while(pa!= NULL && pb!= NULL){
if(pa->data <= pb->data){
q=pa->next;
pa->next=pc->next;
pc->next=pa;
pa=q;
}
else
{
q=pb->next;
pb->next=pc->next;
pc->next=pb;
pb=q;
}
//若其中一个表为空了
if(pa)
pb=pa;
while(pb){
q=pb->next;
pb->next=pc->next;
pc->next=pb;
pb=q;
}
return listc;
}
12、A、B两个单链表递增有序,从A、B中找出公共元素产生单链表C,要求不破坏A、B结点。
从第一个元素起依次比较两个单链表的值:
若元素值不相等,小的那个往后移
若元素值相等,则创建一个新结点,值为两个元素的值(采用尾插法)
LinkList getComValList(LinkList &lista,LinkList &listb){
LNode *pa,*pb,*pc,*q;
LinkList listc=(LinkList)malloc(sizeof(LNode));
pa=lista,pb=listb,pc=listc;
while(pa!=NULL && pb!=NULL){
if(pa->data == pb->data){
//产生一个新结点
q=(LNode*)malloc(sizeof(LNode));
q->data=pa->data;
pc->next=q;
pc=q;
pa=pa->next;
pb=pb->next;
}
else if(pa->data < pb->data){
pa=pa->next;
}
else{
pb=pb->next;
}
}
pc->next=NULL;
return listc;
}
13、A、B两个单链表递增有序,从A、B中找出公共元素存放于A链中。
对两个链表进行扫描,只有同时出现在两个链表的元素才连接到结果表中且只保留一个,其它结点释放。其中一个链表遍历完成后,释放另一个链表的全部结点。
LinkList Union(LinkList &lista,LinkList &listb){
LNode *pa,*pb,*p;
LNode *r;//临时指针,用于删除结点
pa=lista->next;
pb=listb->next;
p=lista;
while(pa & pb){
if(pa->data==pb->data){
p->next=pa;
p=pa;
pa=pa->next;
r=pb;
pb=pb->next;
free(r);
}
else if(pa->data<pb->data){
r=pa;
pa=pa->next;
free(r);
}
else{
r=pb;
pb=pb->next;
free(r);
}
}
while(pa){
r=pa;
pa=pa->next;
free(r);
}
while(pb){
r=pb;
pb=pb->next;
free(r);
}
p->next=NULL;
free(listb);
return lista;
}
14、两个序列分别为A、B,将其存放到链表中,判断B是否使A的连续子序列
分别开始遍历两个链表,若对应数据相等,则指针后移;若对应数据不等,则A从上次开始比较结点的后继结点开始,B链表回到第一个结点开始比较,直到B链表指针指向表尾则表示匹配成功。
int Pattern(LinkList lista,LinkList listb){
LNode *pa,*pb,*p;
pa=lista;
pb=listb;
p=pa;
while(pa && pb){
if(pa->data==pb->data)
pa=pa->next;
pb=pb->next;
}
else {
p=p->next;
pa=p;
pb=listb;
}
if(q==NULL)
return 1;
else
return 0;
}
15、查找单链表中倒数第k个结点,若成功,则输出该结点的data,并返回1,否则返回0。
创建两个指针pa和pb,先让它们都指向第一个结点,让pb往后走k个位置,然后两个指针一起往后走,当pb指向空时,pa指向的位置即为倒数第k个结点。
int getBottomValue(LinkList L,int k){
LNode *pa,*pb;
pa=pb=L;
if(L==NULL || K<=0)
return 0;
for(int i=0;i<k;i++)
pb=pb->next;
while(pb) {
pa=pa->next;
pb=pb->next;
}
print(pa->data);
return 1;
}
16、用单链表保存m个数,并且|data|<=n,设计要求在时间复杂度尽可能高效的算法,对于data绝对值相等的点,仅保留第一次出现的点。
用空间换时间
//max为单链表中结点最大的值
void List(LinkList &L,int max){
int A[max+1];
LNode *p,*pre;
p=L->next;
pre=L;
for(int i=0;i<max+1;i++){
A[i]=0;
}
while(p){
if(p->data<0)
p->data=-(p->data);
if(A[p->data]==0){
A[p->data]=1;
pre=p;
p=p->next;
}
else if(A[p->data]==1){
pre->next=p->next;
free(p);
p=pre->next;
}
}
}
双链表结构体:
typedef struct DNode{
ElemType data;
struct DNode *prior,*next;
}DNode,*DLinkList;
17、判断带头结点的循环双链表是否对称,对称返回1,不对称返回0。
让p从前往后扫描,让q从后往前扫描
表中结点个数为奇数时,当它们指向同一个结点时结束
表中结点个数为偶数时,当p->next=q或者q->prior=p时结束
扫描过程中,只要p->data与q->data不相等,立刻结束
int symmetry(DLinkList L){
DNode *p,*q;
p=L->next;
q=L->prior;
while(p!=q && p->next != q){
if(p->data == q->data){
p=p->next;
q=q->prior;
}
else
return 0;
}
return 1;
}
18、有两个循环单链表,链表头指针分别为h1,h2,试编写函数将h2链表接到h1之后,要求链接后仍保持循环链表形式。
分别找到两个链表的尾指针,将h1的尾指针连接到h2的头指针,将h2的尾指针连接到h1的头指针,最终实现再循环。
LinkList Link(LinkList *h1,LinkList *h2){
LNode *p,*q;
p1=h1;
while(p1->next != h1)
p1=p1->next;
p2=h2;
while(p2->next != h2)
p2=p2->next;
p1->next=h2;
p2->next=h1;
return h1;
}