实验3 带头结点的单链表
1、编写函数void delx(linklist head, datatype x),删除带头结点单链表head中第一个值为x 的结点。 并构造测试用例进行测试。
#include "slnklist.h"
void delx(linklist head,datatype x)
{
linklist pre,p;
pre=head;
p=head->next;
while (p && p->info!=x)
{
pre=p;
p=p->next;
}
if (p)
{
pre->next=p->next;
free(p);
}
}
int main()
{
datatype x;
linklist head;
head=creatbyqueue();
print(head);
printf("请输入要删除的值:");
scanf("%d",&x);
delx(head,x);
print(head);
delList(head);
return 0;
}
2、假设线性表(a1,a2,a3,…an)采用带头结点的单链表存储,请设计算法函数void reverse(linklist head), 将带头结点的单链表head就地倒置,使表变成(an,an-1,…a3.a2,a1)。并构造测试用例进行测试。
#include "slnklist.h"
void reverse(linklist head)
{
linklist p,s;
p=head->next;
head->next=NULL;
while (p)
{
s=p;
p=p->next;
s->next=head->next;
head->next=s;
}
}
int main()
{
datatype x;
linklist head;
head=creatbystack();
print(head);
reverse(head);
print(head);
delList(head);
return 0;
}
3、假设带头结点的单链表head是升序排列的,设计算法函数linklist insert(linklist head,datatype x),将值为x的结点插入到链表head中,并保持链表有序性。分别构造插入到表头、表中和表尾三种情况的测试用例进行测试。
#include "slnklist.h"
void insert(linklist head ,datatype x)
{
linklist pre,p,s;
pre=head;
p=head->next;
while (p && p->info<x)
{
pre=p;
p=p->next;
}
s=(linklist)malloc(sizeof(node));
s->info=x;
s->next=p;
pre->next=s;
}
int main()
{
datatype x;
linklist head;
printf("输入一组升序排列的整数:\n");
head=creatbyqueue();
print(head);
printf("请输入要插入的值:");
scanf("%d",&x);
insert(head,x);
print(head);
delList(head);
return 0;
}
4、编写算法函数void delallx(linklist head, int x),删除带头结点单链表head中所有值为x的结点。
#include "slnklist.h"
void delallx(linklist head,int x)
{
linklist pre,p;
pre=head;
p=head->next;
while(p)
{
while (p &&p->info!=x)
{
pre=p;
p=p->next;
}
if (p)
{
pre->next=p->next;
free(p);
p=pre->next;
}
}
}
int main()
{
datatype x;
linklist head;
head=creatbyqueue();
print(head);
printf("请输入要删除的值:");
scanf("%d",&x);
delallx(head,x);
print(head);
delList(head);
return 0;
}
5、已知线性表存储在带头结点的单链表head中,请设计算法函数void sort(linklist head),将head中的结点按结点值升序排列。
#include "slnklist.h"
void sort(linklist head)
{
linklist pre,q,p,s;
p=head->next;
head->next=NULL;
while (p)
{
s=p;
p=p->next;
pre=head;
q=head->next;
while (q && q->info<s->info)
{
pre=q;
q=q->next;
}
s->next=q;
pre->next=s;
}
}
int main()
{
linklist head;
head=creatbyqueue();
print(head);
sort(head);
print(head);
delList(head);
return 0;
}
6、已知两个带头结点的单链表L1和L2中的结点值均已按升序排序,设计算法函数linklist mergeAscend (linklist L1,linklist L2)将L1和L2合并成一个升序的带头结单链表作为函数的返回结果;设计算法函数linklist mergeDescend (linklist L1,linklist L2)将L1和L2合并成一个降序的带头结单链表作为函数的返回结果;并设计main()函数进行测试。
#include "slnklist.h"
linklist mergeAscend(linklist L1,linklist L2)
{
linklist L3,r3,p,q;
L3=r3=(linklist)malloc(sizeof(node));
p=L1->next;
q=L2->next;
while (p && q)
{
if (p->info<q->info)
{
L1->next=p->next;
r3->next=p;
r3=p;
p=L1->next;
}
else
{
L2->next=q->next;
r3->next=q;
r3=q;
q=L2->next;
}
}
if (p) r3->next=p;
if (q) r3->next=q;
free(L1);
free(L2);
return L3;
}
linklist mergeDescend(linklist L1,linklist L2)
{
linklist L3,r3,p,q;
L3=(linklist)malloc(sizeof(node));
L3->next=NULL;
p=L1->next;
q=L2->next;
while (p && q)
{
if (p->info<q->info)
{
L1->next=p->next;
p->next=L3->next;
L3->next=p;
p=L1->next;
}
else
{
L2->next=q->next;
q->next=L3->next;
L3->next=q;
q=L2->next;
}
}
while (p)
{
L1->next=p->next;
p->next=L3->next;
L3->next=p;
p=L1->next;
}
while (q)
{
L2->next=q->next;
q->next=L3->next;
L3->next=q;
q=L2->next;
}
free(L1);
free(L2);
return L3;
}
int main()
{
linklist h1,h2,h3;
h1=creatbyqueue();
h2=creatbyqueue();
print(h1);
print(h2);
h3=mergeDescend(h1,h2);
print(h3);
delList(h3);
return 0;
}
7、设计一个算法linklist interSection(linklist L1,linklist L2),求两个单链表表示的集合L1和L2的交集,并将结果用一个新的带头结点的单链表保存并返回表头地址。
#include "slnklist.h"
linklist interSection(linklist L1, linklist L2)
{
linklist head,r,p,q,s;
head=r=(linklist)malloc(sizeof(node));
p=L1->next;
while (p)
{
q=L2->next;
while (q && q->info!=p->info)
q=q->next;
if (q)
{
s=(linklist)malloc(sizeof(node));
s->info=p->info;
r->next=s;
r=s;
}
p=p->next;
}
r->next=NULL;
return head;
}
int main()
{
linklist h1,h2,h3;
h1=creatbyqueue();
h2=creatbyqueue();
print(h1);
print(h2);
h3=interSection(h1,h2);
print(h3);
delList(h1);
delList(h2);
delList(h3);
return 0;
}
8、请编写一个算法函数void partion(linklist head),将带头结点的单链表head中的所有值为奇数的结点调整到链表的前面,所有值为偶数的结点调整到链表的后面。
#include "slnklist.h"
void partion(linklist head)
{
linklist pre,p;
pre=head;
p=head->next;
while (p &&p->info%2==1)
{
pre=p;
p=p->next;
}
while (p)
{
while (p &&p->info%2==0)
{
pre=p;
p=p->next;
}
if (p)
{
pre->next=p->next;
p->next=head->next;
head->next=p;
p=pre->next;
}
}
}
int main()
{
linklist head;
head=creatbyqueue();
print(head);
partion(head);
print(head);
delList(head);
return 0;
}
9、编写一个程序,用尽可能快的方法返回带头结点单链表中倒数第k个结点的地址,如果不存在,则返回NULL。
#include "slnklist.h"
linklist search(linklist head,int k)
{
linklist pre,p;
int count=0;
p=head->next;
while (p && count<k)
{
p=p->next;
count++;
}
if (count<k) return NULL;
pre=head->next;
while (p)
{
pre=pre->next;
p=p->next;
}
return pre;
}
int main()
{
int k;
linklist head,p;
head=creatbyqueue();
print(head);
printf("k=");
scanf("%d",&k);
p=search(head,k);
if (p) printf("%d\n",p->info);
else
printf("Not Found!\n");
delList(head);
return 0;
}