head.h
#ifndef HEAD_H__
#define HEAD_H__
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
typedef char datetype;
typedef struct node
{
//数据域
union
{
int len ;
datetype date;
};
//指针域
struct node *next;
}*Linklist,Node;
Linklist Linklistcreate();
Linklist LinklistcreateNode();
void InsetHead(Linklist L,datetype e);
void Linklistshow(Linklist L);
void InsetRear(Linklist L,datetype e1);
void deleteHead(Linklist L);
void Delerear(Linklist L);
void Searchpos(Linklist L,int pos);
void UpdatebyPos(Linklist L,int pos,datetype e);
Linklist Searchbydate(Linklist L,datetype key);
void Linklistupdatebydate(Linklist L,datetype e6,datetype key);
void Linklistdeletebydate(Linklist L,datetype e);
void LinklistRev(Linklist L);
void LinklistSort(Linklist L);
void Insetpos(Linklist L,int pos,datetype e3);
void deleterear(Linklist L,int pos);
#endif
main.c
#include "head.h"
int main(int argc, const char *argv[])
{
Linklist L= Linklistcreate();
if(L==NULL)
return -1;
#if 0
//头插:永远在头部插入
printf("输入链表中的数据元素\n");
datetype e;
int n=5;
for(int i=0;i<n;i++)
{
scanf("%c",&e);
getchar();
InsetHead(L,e);
}
Linklistshow(L);
#endif
//尾插:把新节点存在最后一个节点的后面
datetype e1;int n1=5;
printf("输入插入的数据元素\n");
for(int i=0;i<n1;i++)
{
scanf("%c",&e1);
getchar();
InsetRear(L,e1);
}
Linklistshow(L);
#if 0
//头删
deleteHead(L);
Linklistshow(L);
//尾删
Delerear(L);
Linklistshow(L);
//按位置插入
printf("按位置插入\n");
int pos;
datetype e3;
scanf("%d",&pos);
getchar();
printf("请输入要插入的元素");
scanf("%c",&e3);
Insetpos(L,pos,e3);
Linklistshow(L);
//链表按位置删除
printf("\n输入删除的位置:");
scanf("%d",&pos);
deleterear(L,pos);
Linklistshow(L);
//按位置查找
printf("\n输入查找的位置");
scanf("%d",&pos);
Searchpos(L,pos);
Linklistshow(L);
//链表按位置修改
printf("\n输入修改的位置");
int pos1;
datetype e4;
scanf("%d",&pos1);
getchar();
printf("输入修改的元素");
scanf("%c",&e4);
UpdatebyPos(L,pos1,e4);
Linklistshow(L);
#endif
//链表按元素查找
datetype e5;
printf("\n输入查找的元素\n");
scanf("%c",&e5);
Linklist p=Searchbydate(L,e5);
if(p==NULL)
{
printf("查找失败\n");
}
else
{
printf("%c在链表中出现\n",p->date);
}
//链表按元素修改
datetype e6;datetype e7;
printf("\n请输入要修改的元素\n");
getchar();
scanf("%c",&e6);
printf("\n请输入修改后的值");
getchar();
scanf("%c",&e7);
Linklistupdatebydate(L,e6,e7);
Linklistshow(L);
//链表按元素删除
datetype e8;
printf("\n请输入要删除的元素\n");
getchar();
scanf("%c",&e8);
Linklistdeletebydate(L,e8);
Linklistshow(L);
//链表逆置:
LinklistRev(L);
printf("逆置完成\n");
Linklistshow(L);
//链表排序
LinklistSort(L);
//遍历链表
printf("排序完成\n");
Linklistshow(L);
//空间释放
Free(L);
L=NULL;
return 0;
}
test.c
#include "head.h"
Linklist Linklistcreate()
{
Linklist L=(Linklist)malloc(sizeof(Node));
if(L==NULL)
return NULL;
//节点创建成功
L->len=0;//链表长度初始化;
L->next=NULL;//链表指向为空;
return L;
}
//创建普通节点
Linklist LinklistcreateNode()
{
Linklist p=(Linklist)malloc(sizeof(Node));
if(p==NULL)
return NULL;
p->date=0;
p->next=NULL;//表示创建新节点指针域为空
return p;
}
//头插:永远在头结点后面插入
void InsetHead(Linklist L,datetype e)
{
//1,创建新节点
Linklist p=LinklistcreateNode();
if(p==NULL)
return;
//创建成功
p->date=e;//为新节点赋值;
p->next=L->next;//将原来L的next地址给p的next地址
L->next=p;//将p的地址给L的next
L->len++;//L的长度增加
}
//遍历链表
//无返回值函数
void Linklistshow(Linklist L)
{
printf("输出链表中数据元素\n");
while(L->next)
{
L=L->next;
printf("%c\t",L->date);
}
printf("\n");
}
//单向链表尾插
void InsetRear(Linklist L,datetype e1)
{
//先创建一个新节点
Linklist p=Linklistcreate();
if(p==NULL)
return;
//找到最后一个节点
Linklist q=L;
while(q->next!=NULL)
{
q=q->next;
}
//把新节点插入到最后一个节点的后面
p->date=e1;
q->next=p;
L->len++;
}
//头删:永远山粗头节点的后继节点
//无返回值函数
void deleteHead(Linklist L)
{
//判断链表是否为空
if(L->next==NULL)
return;
//删除
Linklist p=L->next;
L->next=p->next;
free(p);
p=NULL;
L->len--;
}
//尾删:永远只删除最后一个节点
void Delerear(Linklist L)
{
if(L->next==NULL)
return;
Linklist p=L;
for(int i=0;i<L->len-1;i++)
{
p=p->next;
}
free(p->next);
p->next=NULL;
L->len--;
}
//按位置插入
void Insetpos(Linklist L,int pos,datetype e3)
{
if(L->next==NULL||pos<1||pos>L->len+1)
return;
Linklist p=L;
for(int i=0;i<pos-1;i++)
{
p=p->next;
}
Linklist s=Linklistcreate();
s->date=e3;
s->next=p->next;
p->next=s;
L->len++;
}
//链表按位置删除
void deleterear(Linklist L,int pos)
{
if(L->len==0||pos<1||pos>L->len)
{
return;
}
Linklist p=L;
for(int i=0;i<pos-1;i++)
{
p=p->next;
}
Linklist q=p->next;
p->next=q->next;
free(q);
q=NULL;
L->len--;
}
//按位置查找
void Searchpos(Linklist L,int pos)
{
if(L==NULL||pos<1||pos>L->len)
return;
Linklist p=L;
for(int i=0;i<pos;i++)
{
p=p->next;
}
printf("%d位置的元素为%c",pos,p->date);
}
//按位置修改数据元素
void UpdatebyPos(Linklist L,int pos,datetype e)
{
if(L->len==0||pos<1||pos>L->len)
return;
for(int i=0;i<pos;i++)
{
L=L->next;
}
L->date=e;
}
//链表按元素查找
Linklist Searchbydate(Linklist L,datetype key)
{
if(L->len==0)
{
return NULL;
}
Linklist p=L;
for(int i=1;i<=L->len;i++)
{
p=p->next;
if(p->date==key)
{
return p;
}
}
return NULL;
}
//链表按元素修改
void Linklistupdatebydate(Linklist L,datetype e6,datetype key)
{
Linklist q=Searchbydate( L, e6);
if(q==NULL)
{
printf("链表中没有此元素\n");
return;
}
q->date=key;
}
//链表按元素删除
void Linklistdeletebydate(Linklist L,datetype e)
{
if(L->len==0)
return;
Linklist p=L;
for(int i=1;i<L->len;i++)
{
p=p->next;
if(p->date==e)
{
deleterear(L,i);
return;
}
}
}
//链表逆置
void LinklistRev(Linklist L)
{
Linklist p=L->next;//将头节点的位置保存
L->next=NULL;//让头节点孤立
while(p)
{
Linklist k=p;//将p保存于k中
p=p->next;//p开始后移
k->next=L->next;//开始从头节点插入
L->next=k;
}
}
//链表排序
void LinklistSort(Linklist L)
{
Linklist p=L->next;//将头节点的next赋给p
L->next=NULL;//讲头节点与后面分割开
while(p)
{
Linklist t=p;//将偏移后的p保存下来
p=p->next;//p再偏移
Linklist q=L;//将头节点再赋给q
while(q->next!=NULL&&q->next->date<t->date)//判断条件,新加入的节点后不为0并且与要加入的值比较
{
q=q->next;//如果满足就后移
}
//找到了要加入的前一个节点位置,然后按位置加入
t->next=q->next;
q->next=t;