已知带头结点的链表结构定义及头插法建表、尾插法建表和打印链表等函数定义如下(详见slnklist.h文件),基于该文件完成实验题1~实验题9.
#include <stdio.h>
#include <stdlib.h>
#define maxsize 100
typedef int datatype;
typedef struct link_node{
datatype info;
struct link_node *next;
}node;
typedef node *linklist;
/********************************************/
/*函数名称:creatbystack() */
/*函数功能:头插法建立单链表 */
/********************************************/
linklist creatbystack()
{
linklist head,s;
datatype x;
head->next=NULL;
printf("请输入若干整数序列:\n");
scanf("%d",&x);
while(x!=0) /*以0结束输入*/
{
s=(linklist)malloc(sizeof(node)); /*生成待插入结点*/
s->info=x;
s->next=head->next; /*将新结点插入到链表最前面*/
head->next=s;
scanf("%d",&x);
}
return head; /*返回建立的单链表*/
}
/********************************************/
/*函数名称:creatbyqueue() */
/*函数功能:尾插法建立单链表 */
/********************************************/
linklist creatbyqueue()
{
linklist head,r,s;
head=(linklist)malloc(sizeof(node));
datatype x;
head->next=r=NULL;
printf("请输入若干整数序列:/n");
scanf("%d",&x);
while(x!=0) /*以0结束输入*/
{
s=(linklist)malloc(sizeof(node));
s->info=x;
if(head->next==NULL) /*将新结点插入到链表最后面*/
head->next=s;
else r->next=s;
r=s;
scanf("%d",&x);
}
r->next=NULL;
return head; /*返回建立的单链表*/
}
/********************************************/
/*函数名称:print() */
/*函数功能:输入带头结点的单链表 */
/********************************************/
void print(linklist head)
{
linklist p;
int i=0;
p=head->next;
printf("List is:\n");
while(p)
{
printf("%5d",p->info);
p=p->next;
i++;
if(i%10==0) printf("\n");
}
printf("\n");
}
/********************************************/
/*函数名称:delList() */
/*函数功能:释放带头结点的单链表 */
/********************************************/
void delList(linklist head)
{
linklist p=head->next;
while(p)
{
Head->next=p->next;
free(p);
p=head->next;
}
}
(1)编写函数void delx(linklist head,datatype x),删除带头结点单链表head中的第一个值为x的结点,并构造测试用例进行测试(实验代码详见lab3_01.c)
#include <stdio.h>
#include <stdlib.h>
#define maxsize 100
typedef int datatype;
typedef struct link_node{
datatype info;
struct link_node *next;
}node;
typedef node *linklist;
linklist creatbyqueue()
{
linklist head,r,s;
datatype x;
head->next=r=NULL;
printf("请输入若干整数序列:\n");
scanf("%d",&x);
while(x!=0)
{
s=(linklist)malloc(sizeof(node));
s->info=x;
if(head->next==NULL)
head->next=s;
else r->next=s;
r=s;
scanf("%d",&x);
}
if(r) r->next=NULL;
return head;
}
void print(linklist head)
{
linklist p;
int i=0;
p=head->next;
printf("List is:\n");
while(p)
{
printf("%5d",p->info);
p=p->next;
i++;
if(i%10==0) printf("\n");
}
printf("\n");
}
void delList(linklist head)
{
linklist p=head->next;
while(p)
{
head->next=p->next;
free(p);
p=head->next;
}
}
void delx(linklist head,datatype x)
{
linklist p,pre;
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).并构造测试用例进行测试(实验代码详见lab3_02.c)
#include <stdio.h>
#include <stdlib.h>
#define maxsize 100
typedef int datatype;
typedef struct link_node{
datatype info;
struct link_node *next;
}node;
typedef node *linklist;
linklist creatbystack()
{
linklist head,s;
datatype x;
head->next=NULL;
printf("请输入若干整数序列:\n");
scanf("%d",&x);
while(x!=0)
{
s=(linklist)malloc(sizeof(node));
s->info=x;
s->next=head->next;
head->next=s;
scanf("%d",&x);
}
return head;
}
void print(linklist head)
{
linklist p;
int i=0;
p=head->next;
printf("List is:\n");
while(p)
{
printf("%5d",p->info);
p=p->next;
i++;
if(i%10==0) printf("\n");
}
printf("\n");
}
void delList(linklist head)
{
linklist p=head->next;
while(p)
{
head->next=p->next;
free(p);
p=head->next;
}
}
void reverse(linklist head)
{
linklist p,q;
p=head->next;
q=head->next->next;
while(q!=NULL)
{
p->next=q->next;
q->next=head->next;
head->next=q;
q=p->next;
}
}
int main()
{
datatype x;
linklist head;
head=creatbystack();
print(head);
reverse(head);
print(head);
delList(head);
return 0;
}
(3)假设带头结点的单链表head是升序排列的,设计算法函数void insert(linklist head,datatype x),将值为x的结点插入到链表head中,并保持链表的有序性。分别构造插入到表头、表中、表尾3种情况的测试样例进行测试。(实验代码详见lab3_03.c)
#include <stdio.h>
#include <stdlib.h>
#define maxsize 100
typedef int datatype;
typedef struct link_node{
datatype info;
struct link_node *next;
}node;
typedef node *linklist;
linklist creatbyqueue()
{
linklist head,r,s;
datatype x;
head->next=r=NULL;
printf("请输入若干整数序列:\n");
scanf("%d",&x);
while(x!=0)
{
s=(linklist)malloc(sizeof(node));
s->info=x;
if(head->next==NULL)
head->next=s;
else r->next=s;
r=s;
scanf("%d",&x);
}
if(r) r->next=NULL;
return head;
}
void print(linklist head)
{
linklist p;
int i=0;
p=head->next;
printf("List is:\n");
while(p)
{
printf("%5d",p->info);
p=p->next;
i++;
if(i%10==0) printf("\n");
}
printf("\n");
}
void delList(linklist head)
{
linklist p=head->next;
while(p)
{
head->next=p->next;
free(p);
p=head->next;
}
}
void insert(linklist head,datatype x)
{
linklist p,pre,s,r;
pre=head;
p=head->next;
s=(linklist)malloc(sizeof(node));
s->info=x;
s->next=NULL;
while(p && p->info<x)
{
pre=p;
p=p->next;
}
if(p)
{
if(!pre)
{
s->next=p;
head->next=s;
}
else
{
s->next=p;
pre->next=s;
}
}
else
{
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 linklist delallx(linklist head,int x),删除带头结点单链表head中所有值为x的结点。
#include <stdio.h>
#include <stdlib.h>
#define maxsize 100
typedef int datatype;
typedef struct link_node{
datatype info;
struct link_node *next;
}node;
typedef node *linklist;
linklist creatbyqueue()
{
linklist head,r,s;
datatype x;
head->next=r=NULL;
printf("请输入若干整数序列:\n");
scanf("%d",&x);
while(x!=0)
{
s=(linklist)malloc(sizeof(node));
s->info=x;
if(head->next==NULL)
head->next=s;
else r->next=s;
r=s;
scanf("%d",&x);
}
if(r) r->next=NULL;
return head;
}
void print(linklist head)
{
linklist p;
int i=0;
p=head->next;
printf("List is:\n");
while(p)
{
printf("%5d",p->info);
p=p->next;
i++;
if(i%10==0) printf("\n");
}
printf("\n");
}
void delList(linklist head)
{
linklist p=head->next;
while(p)
{
head->next=p->next;
free(p);
p=head->next;
}
}
void linklist_delallx(linklist head,int x)
{
linklist p,pre;
p=head->next;
pre=head;
while(p)
{
if(p->info==x&&!pre)
{
head->next=p->next;
pre=head;
p=p->next;
}
else if(p->info==x&&pre)
{
pre->next=p->next;
p=p->next;
}
else
{
pre=p;
p=p->next;
}
}
}
int main()
{
datatype x;
linklist head;
head=creatbyqueue();
print(head);
printf("请输入要删除的值:");
scanf("%d",&x);
linklist_delallx(head,x);
print(head);
delList(head);
return 0;
}
(5)已知线性表存储在带头结点的单链表head中,请设计算法函数void sort(linklist head),将head中的结点按结点值升序排列。(实验代码详见lab3_05.c)
#include <stdio.h>
#include <stdlib.h>
#define maxsize 100
typedef int datatype;
typedef struct link_node{
datatype info;
struct link_node *next;
}node;
typedef node *linklist;
linklist creatbyqueue()
{
linklist head,r,s;
datatype x;
head->next=r=NULL;
printf("请输入若干整数序列:\n");
scanf("%d",&x);
while(x!=0)
{
s=(linklist)malloc(sizeof(node));
s->info=x;
if(head->next==NULL)
head->next=s;
else r->next=s;
r=s;
scanf("%d",&x);
}
if(r) r->next=NULL;
return head;
}
void print(linklist head)
{
linklist p;
int i=0;
p=head->next;
printf("List is:\n");
while(p)
{
printf("%5d",p->info);
p=p->next;
i++;
if(i%10==0) printf("\n");
}
printf("\n");
}
void delList(linklist head)
{
linklist p=head->next;
while(p)
{
head->next=p->next;
free(p);
p=head->next;
}
}
void sort(linklist head)
{
linklist p,q,n,r;//n的作用是每次冒泡排序后指向最后一个数(找出最大值)的前一个数,效果是下一次的冒泡排序次数减少一次,提高了代码效率
n=NULL;
r=head;
while(r->next!=n)//单链表不为空
{
p=head;
q=p->next;
while(q->next!=n)
{
if(q->info > q->next->info)
{
p->next=q->next;
q->next=q->next->next;
p->next->next=q;
p=p->next;
}
else
{
p=p->next;
q=q->next;
}
}
n=q;
}
}
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 mergeDesend(linklist L1,linklist L2)将L1和L2合并成一个降序的带头结点的单链表作为函数的返回结果;并设计main()函数进行测试。(要求利用原链表中的结点,不需复制新结点)(实验代码详见lab3_06.c)
#include <stdio.h>
#include <stdlib.h>
#define maxsize 100
typedef int datatype;
typedef struct link_node{
datatype info;
struct link_node *next;
}node;
typedef node *linklist;
linklist creatbyqueue()
{
linklist head,r,s;
datatype x;
head=(linklist)malloc(sizeof(node));
head->next=r=NULL;
printf("请输入若干整数序列:\n");
scanf("%d",&x);
while(x!=0)
{
s=(linklist)malloc(sizeof(node));
s->info=x;
if(head->next==NULL)
head->next=s;
else r->next=s;
r=s;
scanf("%d",&x);
}
if(r) r->next=NULL;
return head;
}
void print(linklist head)
{
linklist p;
int i=0;
p=head->next;
printf("List is:\n");
while(p)
{
printf("%5d",p->info);
p=p->next;
i++;
if(i%10==0) printf("\n");
}
printf("\n");
}
void delList(linklist head)
{
linklist p=head->next;
while(p)
{
head->next=p->next;
free(p);
p=head->next;
}
}
/*linklist mergeAscend(linklist L1,linklist L2)
{
linklist head,p,q;
p=L1->next;
q=L2->next;
head=(linklist)malloc(sizeof(node));
linklist r=head;
while(p&&q)
{
if(p->info<=q->info)
{
r->next=p;
p=p->next;
r=r->next;
}
else
{
r->next=q;
q=q->next;
r=r->next;
}
}
if(p==NULL)
r->next=q;
else
r->next=p;
return head;
}*/
linklist mergeDesend(linklist L1,linklist L2)
{
linklist p1,p2,p1next,p2next,head;
head=L1;
p1=L1->next;
p2=L2->next;
head->next=NULL;
free(L2);
while(p1&&p2)
{
if(p1->info<=p2->info)
{
p1next=p1->next;
p1->next=head->next;
head->next=p1;
p1=p1next;
}
else
{
p2next=p2->next;
p2->next=head->next;
head->next=p2;
p2=p2next;
}
}
while(p1)
{
p1next=p1->next;
p1->next=head->next;
head->next=p1;
p1=p1next;
}
while(p2)
{
p2next=p2->next;
p2->next=head->next;
head->next=p2;
p2=p2next;
}
return head;
}
int main()
{
linklist h1,h2,h3;
h1=creatbyqueue();
h2=creatbyqueue();
print(h1);
print(h2);
/*h3=mergeAscend(h1,h2);
print(h3);*/
h3=mergeDesend(h1,h2);
print(h3);
delList(h3);
return 0;
}
(7)设计一个算法linklist interSection(linklist L1,linklist L2),求两个单链表表示的集合L1和L2的交集,并将结果用一个新的带头结点的单链表保存并返回表头地址。(实验代码详见lab3_07.c)
#include <stdio.h>
#include <stdlib.h>
#define maxsize 100
typedef int datatype;
typedef struct link_node{
datatype info;
struct link_node *next;
}node;
typedef node *linklist;
linklist creatbyqueue()
{
linklist head,r,s;
head=(linklist)malloc(sizeof(node));
datatype x;
head->next=r=NULL;
printf("请输入若干整数序列:\n");
scanf("%d",&x);
while(x!=0)
{
s=(linklist)malloc(sizeof(node));
s->info=x;
if(head->next==NULL)
head->next=s;
else r->next=s;
r=s;
scanf("%d",&x);
}
r->next=NULL;
return head;
}
void print(linklist head)
{
linklist p;
int i=0;
p=head->next;
printf("List is:\n");
while(p)
{
printf("%5d",p->info);
p=p->next;
i++;
if(i%10==0) printf("\n");
}
printf("\n");
}
void delList(linklist head)
{
linklist p=head->next;
while(p)
{
head->next=p->next;
free(p);
p=head->next;
}
}
linklist interSection(linklist L1,linklist L2)
{
linklist head,p1,p2,s,r;
p1=L1->next;
p2=L2->next;
head=(linklist)malloc(sizeof(node));
head->next=NULL;
r=head;
while(p1)
{
while(p2)
{
if(p1->info==p2->info)
{
s=(linklist)malloc(sizeof(node));
s->info=p1->info;
r->next=s;
r=r->next;
}
p2=p2->next;
}
p1=p1->next;
p2=L2->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中的所有值为奇数的结点调整到链表的前面,所有值为偶数的结点调整到链表的后面。(实验代码详见lab3_08.c)
#include <stdio.h>
#include <stdlib.h>
#define maxsize 100
typedef int datatype;
typedef struct link_node{
datatype info;
struct link_node *next;
}node;
typedef node *linklist;
linklist creatbyqueue()
{
linklist head,r,s;
datatype x;
head->next=r=NULL;
printf("请输入若干整数序列:\n");
scanf("%d",&x);
while(x!=0)
{
s=(linklist)malloc(sizeof(node));
s->info=x;
if(head->next==NULL)
head->next=s;
else r->next=s;
r=s;
scanf("%d",&x);
}
if(r) r->next=NULL;
return head;
}
void print(linklist head)
{
linklist p;
int i=0;
p=head->next;
printf("List is:\n");
while(p)
{
printf("%5d",p->info);
p=p->next;
i++;
if(i%10==0) printf("\n");
}
printf("\n");
}
void delList(linklist head)
{
linklist p=head->next;
while(p)
{
head->next=p->next;
free(p);
p=head->next;
}
}
void partion(linklist head)
{
linklist p,q;
q=head->next;
p=head->next->next;
while(p)
{
if(p->info%2)
{
q->next=p->next;
p->next=head->next;
head->next=p;
p=q->next;
}
else
{
q=p;
p=p->next;
}
}
}
int main()
{
linklist head;
head=creatbyqueue();
print(head);
partion(head);
print(head);
delList(head);
return 0;
}
(9)编写一个程序,用尽可能快的方法返回带头结点单链表中倒数第k个结点的值,如果不存在,则返回NULL。(实验代码详见lab3_09.c)
#include <stdio.h>
#include <stdlib.h>
#define maxsize 100
typedef int datatype;
typedef struct link_node{
datatype info;
struct link_node *next;
}node;
typedef node *linklist;
linklist creatbyqueue()
{
linklist head,r,s;
datatype x;
head->next=r=NULL;
printf("请输入若干整数序列:\n");
scanf("%d",&x);
while(x!=0)
{
s=(linklist)malloc(sizeof(node));
s->info=x;
if(head->next==NULL)
head->next=s;
else r->next=s;
r=s;
scanf("%d",&x);
}
if(r) r->next=NULL;
return head;
}
void print(linklist head)
{
linklist p;
int i=0;
p=head->next;
printf("List is:\n");
while(p)
{
printf("%5d",p->info);
p=p->next;
i++;
if(i%10==0) printf("\n");
}
printf("\n");
}
void delList(linklist head)
{
linklist p=head->next;
while(p)
{
head->next=p->next;
free(p);
p=head->next;
}
}
linklist search(linklist head,int k)
{
linklist p,r;
int length=0;
int j=0;
r=head;
while(r)
{
r=r->next;
length++;
}
p=head;
while(p && j!=length-k)
{
p=p->next;
j++;
}
if(!p)
return NULL;
else
return p;
}
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;
}