一、实验要求
(1).尾插法创建单链表,打印创建结果。
(2).头插法创建单链表,打印创建结果。
(3).销毁单链表。
(4).求链表长度。
(5).求单链表中第i个元素(函数),若不存在,报错。
(6).在第i个结点前插入值为x的结点。
(7).链表中查找元素值为x的结点,成功返回结点指针,失败报错。
(8).删除单链表中第i个元素结点。
(9).在一个递增有序的单链表L中插入一个值为x的元素,并保持其递增有序特性。
(10).将单链表L中的奇数项和偶数项结点分解开(元素值为奇数、偶数),分别放入新的单链表中,然后原表和新表元素同时输出到屏幕上,以便对照求解结果。
(11).求两个递增有序单链表L1和L2中的公共元素,放入新的单链表L3中。
(12).删除递增有序单链表中的重复元素,要求时间性能最好。
(13).递增有序单链表L1、L2,不申请新结点,利用原表结点对2表进行合并,并使得合并后成为一个集合,合并后用L1的头结点作为头结点,删除L2的头结点,要求时间性能最好。
二、数据结构设计
typedef int elementType ;
typedef struct slNode{ //结构体的定义
elementType data;
struct slNode * next;
}node,*linkList;
三、代码实现
#ifndef _LINKEDLIST_H_
#define _LINKEDLIST_H_
#include <stdio.h>
#include <stdlib.h>
typedef int elementType ;
typedef struct slNode{ //结构体的定义
elementType data;
struct slNode * next;
}node,*linkList;
//初始化函数
void initList(node ** L)
{
(*L)->next=NULL;
}
//1.尾插法创建单链表,打印创建结果。
void rearCreatList(node * * L)
{
elementType x;
node * u,*r;
*L=(node *)malloc(sizeof(node)); //创建头结点
initList(L);
r = *L;
printf("按-1结束,请输入链表元素:\n");
scanf("%d",&x);
while(x!=-1)
{
u=(node *)malloc(sizeof(node)); //创建新结点
u->data=x;
u->next=r->next;
r->next=u; //将新节点链接表尾
r=u;
scanf("%d",&x);
}
printf("链表L为:");
print(L);
}
//2.头插法创建单链表,打印创建结果。
void headCreatList(node * * L)
{
elementType x;
node * u;
*L=(node *)malloc(sizeof(node)); //创建尾结点
initList(L);
printf("按-1结束,请输入链表元素:\n");
scanf("%d",&x);
while(x!=-1)
{
u=(node *)malloc(sizeof(node)); //创建新结点
u->data=x;
u->next=(*L)->next;
(*L)->next=u; //将新节点链接表头,使之成为首节点
scanf("%d",&x);
}
printf("链表L为:");
print(L);
}
//打印函数
void print(node * *L)
{
node *p;
p=(*L)->next;
while(p!=NULL)
{
printf("%d ",p->data);
p=p->next;
}
printf("\n");
}
//3.销毁单链表
void destroyList(node **L)
{
node *p,*q;
p=*L; //初始化时p指向头结点
while(p!=NULL) //p不为空时执行
{
q=p->next; //q变量记录p的下一个节点
free (p); //释放p结点
p=q; //把q赋值给p
}
}
//4.求链表长度。
int listLen(node **L)
{
int c=0; //计数器
node *p;
p=(*L)->next;
while(p!=NULL)
{
c++;
p=p->next;
}
return c;
}
//5.求单链表中第i个元素(函数),若不存在,报错。
int getElementList(node **L,elementType * x)
{
int i;
node *p;
p=(*L)->next;
printf("请输入元素位置:");
scanf("%d",&i);
if(i<1 || i>listLen(L)) //判断位置是否出错
{
printf("不存在该位置!\n");
return 0;
}
else{
while(i--)
{
p=p->next;
}
* x=p->data;
return 1;
}
}
//6.在第i个结点前插入值为x的结点。
void insertList(node **L)
{
int i;
node *p,*u,*q; //p为第i-1个结点的指针,u为插入的新节点,q为第i个结点的指针
elementType x;
p=*L;
printf("请输入插入元素位置:");
scanf("%d",&i);
i--;
printf("请输入插入的元素:");
scanf("%d",&x);
if(i<0 || i>(listLen(L)+1))
{
printf("不存在该位置!\n"); //判断位置是否出错
}
else{
while(i--)
{
p=p->next;
}
u=(node *)malloc(sizeof(node)); //生成插入的节点
q=p->next;
u->data=x;
u->next=q; //链接插入的节点
p->next=u;
printf("插入的元素后链表为:");
print(L);
}
}
//7.链表中查找元素值为x的结点,成功返回结点指针,失败报错。
node * returnP(node **L)
{
elementType x;
node * p;
p=(*L)->next;
printf("请输入元素:");
scanf("%d",&x);
while(p!=NULL&&p->data!=x )
{
p=p->next;
}
if(p==NULL)
{
printf("不存在该元素!\n"); //失败报错
}
else{
printf("元素存在!");
}
return p;
}
//8.删除单链表中第i个元素结点。
void deleteList(node **L)
{
int i;
node *p,*u,*q; //p为第i-1个结点的指针,u第i+1个结点的指针,q为第i个结点的指针
p=*L;
printf("请输入删除元素位置:");
scanf("%d",&i);
i--;
if(i<0 || i>listLen(&*L))
{
printf("不存在该位置!\n"); //判断位置是否出错
}
else{
while(i--)
{
p=p->next;
}
u=p->next;
q=p->next->next;
p->next=q;
free(u);
printf("删除元素后链表L为:");
print(L);
}
}
//9.在一个递增有序的单链表L中插入一个值为x的元素,并保持其递增有序特性。
void insertOrderList(node **L)
{
node *p,*u; //u指向插入的新节点
elementType x;
p=(*L);
printf("请输入元素:");
scanf("%d",&x);
while(p->next!=NULL&&p->next->data<=x)
{
p=p->next;
}
u=(node *)malloc(sizeof(node)); //申请新节点
u->data=x;
u->next=p->next;
p->next=u;
printf("插入元素后链表L为:");
print(L);
}
//10.将单链表L中的奇数项和偶数项结点分解开(元素值为奇数、偶数),分别放入新的单链表中,然后原表和新表元素同时输出到屏幕上,以便对照求解结果
void analyzeList(node **L)
{
node * p;
node *L1,*L2,*M,*N,*u,*t;
p=(*L)->next; //初始化时p指向头结点L
L1=(node *)malloc(sizeof(node)); //生成头指针L1
L2=(node *)malloc(sizeof(node)); //生成头指针L2
M=L1; //初始化时M指向头结点L1
N=L2; //初始化时N指向头结点L2
initList(&L1); //初始化L1
initList(&L2); //初始化L2
while(p!=NULL) //如果链表不为空,继续执行
{
if(p->data%2==0) //如果是偶数,插入链表L1
{
u=(node *)malloc(sizeof(node)); //创建新结点
u->data=p->data; //采用尾插法,创建链表
u->next=M->next;
M->next=u;
M=u;
}
else{ //如果是奇数,插入链表L2
t=(node *)malloc(sizeof(node)); //创建新结点
t->data=p->data; //采用尾插法,创建链表
t->next=N->next;
N->next=t;
N=t;
}
p=p->next; //p后移一位
}
printf("偶数项L1为:");
print(&L1); //打印链表L1
printf("奇数项L2为:");
print(&L2); //打印链表L2
destroyList(&L1); //销毁链表L1
destroyList(&L2); //销毁链表L2
}
//11.求两个递增有序单链表L1和L2中的公共元素,放入新的单链表L3中。
void commonList()
{
node *L1,*L2,*L3;
node *p,*q,* u,*r; //p,q分别指向L1,L2,u为L3插入的新节点
rearCreatList(&L1);
rearCreatList(&L2);
L3=(node *)malloc(sizeof(node));
initList(&L3);
r =L3;
printf("链表L1的元素为:");
print(&L1);
printf("链表L2的元素为:");
print(&L2);
p=L1->next; //p指向L1的头结点
q=L2->next; //q指向L2的头结点
while(p!=NULL&&q!=NULL)
{
if(p->data==q->data)
{
u=(node *)malloc(sizeof(node));
u->data=p->data;
u->next=r->next; //用了尾插法
r->next=u;
r=u;
p=p->next;
q=q->next;
}
else if((p->data) > (q->data))
{
q=q->next;
}
else{
p=p->next;
}
}
printf("\n");
printf("链表L3的元素为:");
print(&L3);
destroyList(&L1);
destroyList(&L2);
destroyList(&L3);
}
//12.删除递增有序单链表中的重复元素,要求时间性能最好。
void deleteReaptElement(node ** L)
{
node *p,*q; //定义两个指针
p=(*L)->next; //初始化时p指向首节点
q=(*L)->next->next; //初始化时q指向首节点之后的节点
while(q!=NULL)
{
if(p->data==q->data)
{
q=q->next; //如果p->data==q->data,q后移一位
}
else{
p->next->data=q->data; //如果不相等,把q->data赋值给p->next->data
p=p->next; //p后移一位
}
}
destroyList(&(p->next)); //销毁p->next以后的节点
p->next=NULL; //把p->next->next置为空
printf("删除重复元素后链表L为:");
print(& L); //输出链表L
}
//13.递增有序单链表L1、L2,不申请新结点,利用原表结点对2表进行合并,并使得合并后成为一个集合,合并后用L1的头结点作为头结点,删除L2的头结点,要求时间性能最好。
void mergeList()
{
node * L1,* L2; //定义两个链表L1,L2
node *p,*q,*u; //p,q分别指向L1,L2,u指向被删除的节点
rearCreatList(&L1); //创建链表L1
rearCreatList(&L2); //创建链表L2
p=L1; //初始化时指向头结点L1
q=L2; //初始化时指向头结点L2
while(p->next!=NULL && q->next!=NULL)
{
if(p->next->data==q->next->data)
{
u=q->next; //把要删除的节点指针赋值给u
q->next=u->next; //连接要删除结点的前后结点
free(u); //如果L1,L2有重复元素,删除L2中的重复元素
p=p->next; //p向后移一位,q不移
}
else if((p->next->data)>(q->next->data))
{
q=q->next; //如果(p->next->data)>(q->next->data),q向后移一位
}
else{
p=p->next; //如果(p->next->data)<(q->next->data),p向后移一位
}
}
if(p->next!=NULL) //如果p没有指向尾结点,使它指向尾结点
{
while(p->next!=NULL)
{
p=p->next;
}
}
p->next=L2->next; //L1尾结点p连接L2首节点
free(L2); //删除L2头结点
printf("合并后L1为:");
print(&L1);
destroyList(&L1); //销毁链表
}
#endif // _LINKEDLIST_H_
#include <stdio.h>
#include <stdlib.h>
#include "linkedList.h"
int main()
{
int len,i=100;
elementType x;
node * L;
while(i!=0)
{
printf("******************************************************************************\n");
printf("按0退出程序并销毁单链表\n");
printf("按1尾插法创建单链表\n");
printf("按2头插法创建单链表\n");
printf("按3求链表长度\n");
printf("按4求单链表中第i个元素\n");
printf("按5在第i个结点前插入值为x的结点\n");
printf("按6查找元素值为x的结点\n");
printf("按7删除单链表中第i个元素结点\n");
printf("按8在一个递增有序的单链表L中插入一个值为x的元素,并保持其递增有序特性\n");
printf("按9将单链表L中的奇数项和偶数项结点分解开\n");
printf("按10求两个递增有序单链表L1和L2中的公共元素,放入新的单链表L3中\n");
printf("按11删除递增有序单链表中的重复元素\n");
printf("按12递增有序单链表L1、L2,不申请新结点,利用原表结点对2表进行合并,并使得合并后成为一个集合,合并后用L1的头结点作为头结点,删除L2的头结点\n");
printf("*******************************************************************************\n");
scanf("%d",&i);
switch(i)
{
case 0:
destroyList(&L);
return ;
case 1:
rearCreatList(&L);
break;
case 2:
headCreatList(&L);
break;
case 3:
len=listLen(&L);
printf("链表长度为:%d",len);
break;
case 4:
if(getElementList(&L,&x))
{
printf("第i个元素为:%d\n",x);
}
break;
case 5:
insertList(&L);
break;
case 6:
returnP(&L);
break;
case 7:
deleteList(&L);
break;
case 8:
insertOrderList(&L);
break;
case 9:
analyzeList(&L);
break;
case 10:
commonList();
break;
case 11:
deleteReaptElement(&* L);
break;
case 12:
mergeList();
break;
}
system("PAUSE");
system("CLS");
}
destroyList(&L);
return 0;
}