#include<stdlib.h>
#include<stdio.h>
#define ERROR 0
#define OK 1
typedef char ElemType;
typedef struct Node //结点类型定义
{
ElemType data;
struct Node * next;
}Node,*LinkList; //*LinkList为结构指针类型
LinkList Init() //初始化
{
LinkList L;
L=(LinkList)malloc(sizeof(Node)); //建立头结点
L->next=NULL; //建立空的单链表L
return L;
}
void CreateFromHead(LinkList L)//L是带头结点的空链表头指针,通过键盘输入表中元素值,利用头插法建立单链表L
{
Node *s;
char c;
int flag=1;
while(flag) //flag初值为1,当输入‘$’时,置flag为0,建表结束
{
c=getchar();
if(c!='$')
{
s=(Node *)malloc(sizeof(Node)); //建立新结点s
s->data=c;
s->next=L->next; //将s结点插入表头
L->next=s;
}
else
{
flag=0;
}
}
}
void NiZhi(LinkList L)
{
Node *p,*front,*back;
back=NULL;p=L->next;
while(p!=NULL)
{
front=p->next;
p->next=back;
back=p;
p=front;
}
L->next=back;
}
void CreateFromTail(LinkList L) //L是带有头结点的空链表头指针,通过键盘输入元素值,利用尾插法建立单链表L
{
Node *r,*s;
int flag=1; //设置一个标志,初值为1,当输入“$”时,flag为0,建表结束
r=L; //r指针动态指向链表的当前表尾,以便于做尾插入,其初值指向头结点
char c;
while(flag) //循环输入表中元素值 ,将建立新结点s插入表尾
{
c=getchar();
if(c!='$')
{
s=(Node * )malloc(sizeof(Node));
s->data=c;
r->next=s;
r=s;
}
else
{
flag=0;
r->next=NULL; //将最后一个结点的next域置为空,表示链表的结束
}
}
}
Node *Get(LinkList L,int i)
{
int j;
Node *p;
if(i<=0)
{
return NULL;
}
p=L;
j=0; //从头结点开始扫描
if(i>ListLength(p))
{
printf("查找位置不合理!\n");
return NULL;
} //找不到,查找位置超出表长
while(p->next!=NULL&&j<i)
{
p=p->next;//扫描下一结点
j++; //已扫描结点计数器
}
if(i=j)
{
return p; //找到了第i个结点
}
}
int Locate(LinkList L,ElemType key)
{
int j=1;
Node *p;
p=L->next; //从表中第一个结点开始
while(p!=NULL)
{ //当前表未查完
if(key==p->data)
{
printf("查找字符%c是L1中第%d个元素\n",key,j);
p=p->next;
j++;
}
else
{
p=p->next;
j++;
}
}//找到结点值=key时退出循环 ;
return 0;
}
int ListLength(LinkList L)
{
Node *p;
p=L->next;
int j=0; //用来存放单链表的长度
while(p!=NULL)
{
p=p->next;
j++;
}
return j; //j为求得的单链表的长度
}
int InsList(LinkList L,int i,ElemType e)
{
Node *pre,*s;
int k;
if(i<=0)
{
return ERROR;
}
pre=L;
k=0;//从头开始查找第i-1个结点
while(pre!=NULL&&k<i-1) //表未查完且未查到第i-1个时重复,找到pre指向第i-1个
{
pre=pre->next;
k=k+1;
}
if(pre==NULL) //如当前位置pre为空表示已找完,但还未数到第i个,说明插入位置不合理
{
printf("插入位置不合理!");
return ERROR;
}
s=(Node *)malloc(sizeof(Node)); //申请一个新结点s
s->data=e; //值e插入s的数据域
s->next=pre->next;//修改指针,完成插入操作
pre->next=s;
return OK;
}
ElemType DelList(LinkList L,int i) //删除结点
{
ElemType e;
Node *pre,*r;
int k;
pre=L;k=0;
while(pre->next!=NULL&&k<i) //寻找被删除的结点i的前驱结点i-1使p指向它
{
pre=pre->next;
k=k+1;
}
if(pre->next==NULL)
{
printf("删除结点的位置i不合理!");
return ERROR;
} //查找第i-1个结点
r=pre->next;
pre->next=r->next; //修改指针,删除结点r
e=r->data;
free(r); //释放被删除结点所占的内存空间
return e;
}
LinkList MergeLinkList(LinkList LA,LinkList LB) //将递增有序的单链表LA和LB合成一个递增有序的单链表LC
{
Node *pa,*pb;
LinkList LC=Init();
//将LC初置空表 。pa和pb分别指向两个单链表LA和LB中的第一个结点,r 初置为LC且r始终指向LC的表尾
pa=LA->next;
pb=LB->next;
LC=LA;
LC->next=NULL;
Node *r=LC;//当两个表中均未处理完时,比较选择将较小值结点插入到新表LC中
while(pa!=NULL&&pb!=NULL)
{
if(pa->data<=pb->data)
{
r->next=pa;r=pa;pa=pa->next;
}
else
{
r->next=pb;r=pb;pb=pb->next;
}
}
if(pa) //若表LA未完,将表LA中后续元素链到新表LC表尾
{
r->next=pa;
}
else
{
r->next=pb;
}
free(LB);
return (LC);
}
void Print(LinkList L)//输出函数
{
Node *p=L->next;
while(p)
{
printf("%c",p->data);
p=p->next;
}
}
int Empty(LinkList L) //判断是否为空
{
if(L->next==NULL)
{
return 1;
}
else
{
return 0;
}
}
int main()
{
int a;
int b;
int c;
int d;
int e;
Node * w;
printf("请输入两个表L1和L2,以“$”结束:\n");
LinkList L1;
LinkList L2;
L1=Init();
L2=Init();
CreateFromHead(L1);
printf("\n头插法建表L1:\n");
Print(L1);
NiZhi(L1);
printf("\n逆置后为L1:\n");
Print(L1);
printf("\n\n");
CreateFromTail(L2);
printf("尾插法建表L2:");
Print(L2);
ListLength(L1);
printf("\n\nL1的表长为:%d\n",ListLength(L1));
printf("L1中查找序号为:\n");
scanf("%d",&a);
w=Get(L1,a);
printf("L1中第%d个元素的值是%c\n",a,w->data);
printf("\nL1中要查找的字符为:");
scanf("%*c%c",&b);
Locate(L1,b);
printf("\nL1中插入的位置为:");
scanf("%d",&c);
printf("插入的字符为:");
scanf("%*c%c",&d);
InsList(L1,c,d);
printf("在L1中第%d个位置插入值为%c的新结点后为:\n",c,d);
Print(L1);
printf("\n\n删除L2的位置为:");
scanf("%d",&e);
DelList(L2,e);
printf("删除后的L2为:");
Print(L2);
if(Empty(L1))
{
printf("\n\n表L1为空!\n");
}
else
{
printf("\n表L1非空!");
}
printf("\n\nL1和L2合并后为:");
Print(MergeLinkList(L1,L2));
return 0;
}
运行结果如下: