此链表可以实现创建,输入,序号查找,数值查找,插入,删除,输出等功能
代码:
#include<stdio.h>
#include<stdlib.h>
//链表的结构体
typedef struct linklist{
int data;//存放数字
struct linklist *next;//指向下一个节点的指针
}*LinkList;
//菜单 (用来画出菜单的函数)
void Menu(void);
//长度(用来测量链表长度的函数)
int Length(LinkList head);
//创建一个新链表(其实就是将前面的链表清除后建个新的表头)
void CreateList(LinkList *head);
//输入
void IntoList(LinkList head);
//按序号查找(输入序号,查找该序号上的数字)
void Findkth(LinkList head);
//按值查找(输入值,查找其第一次出现的位置且求出其总共出现的次数)
void Find(LinkList head);
//插入(输入序号在该位置插入数字)
void Insert(LinkList head);
//删除(输入序号,删除该位置上的数字)
void Delete(LinkList head);
//输出(将链表中的值全部输出)
void OutList(LinkList head);
//清除(将链表全部释放)
void ClearList(LinkList head);
int main(void)
{
LinkList head=NULL;//用来当表头
int trigger;//用户选择服务
while(1)
{
Menu();
scanf("%d",&trigger);
system("cls");
switch(trigger)
{
case 1: CreateList(&head);
break;
case 2: IntoList(head);
break;
case 3: Findkth(head);
break;
case 4: Find(head);
break;
case 5: Insert(head);
break;
case 6: Delete(head);
break;
case 7: OutList(head);
break;
case 8: ClearList(head);
break;
case 0: ClearList(head);
return 0;
}
}
return 0;
}
void Menu(void)
{
puts("---------------------");
puts("1.创建一个新链表");
puts("2.输入数据");
puts("3.按序号查找");
puts("4.按值查找");
puts("5.插入");
puts("6.删除");
puts("7.输出数据");
puts("8.清空链表");
puts("0.退出");
puts("---------------------");
}
//长度
int Length(LinkList head)
{
int i;
LinkList pre;
pre=head;
for(i=0;pre->next!=NULL;i++)//当pre->next!=NULL时说明该链表到头了
{
pre=pre->next;//若无到头,则继续往下一个节点移动
}
return i;//将长度返回
}
//创建新链表
void CreateList(LinkList *head)//这里面传入了前面旧链表的表头的地址
{
if(*head!=NULL) ClearList(*head);//如果旧链表不是空链表就先把它存的东西释放掉
*head=(LinkList)malloc(sizeof(struct linklist));//为旧表头申请个新的空间,他就成新表头了
if(*head==NULL)//判断表头新建成没
{
printf("新建链表失败!!!\n");
}else{
(*head)->next=NULL;
printf("新建链表成功!!!\n");
}
}
/*输入*/
void IntoList(LinkList head)
{
LinkList pri,pre;
//先让pri指向表尾
for(pri=head;pri->next!=NULL;pri=pri->next)
continue;
while(1)
{
pre=(LinkList)malloc(sizeof(struct linklist));//为现在要输入的数字申请空间
if(pre==NULL)
{
printf("申请空间失败!!!\n");
break;
}
//用户输入数字
int number;
printf("请输入要存储的数字(若已输入完毕则输入-1以结束输入):\n");
scanf("%d",&number);
//判断数字是否为负一,不是则存,是则退出该函数
if(number!=-1)
{
pre->data=number;
pre->next=NULL;
pri->next=pre;
pri=pre;
puts("输入完成!!!");
}else return;
}
}
//按序号找值
void Findkth(LinkList head)//这里将表头传进来
{
int number,i;//一个位置,一个为该位置上的值
LinkList pre;//用来查找的指针
pre=head;//指向表头
puts("请输入你要查看序号:");
scanf("%d",&number);
//开始查找该位置上的值
if(number<=0||number>Length(head)) //位置过小或超过表的长度
{
puts("数字违规!!!!");
}
for(i=0;pre!=NULL&&i<=number;i++)//遍历该链表
{
//当pre指向该位置时
if(i==number)
{
printf("第%d个位置上的数字是%d\n",number,pre->data);//输出该位置上的值
return;
}
pre=pre->next;//没找到则指向下一个节点
}
}
//按值查找
void Find(LinkList head)//这里只要传入表头就行
{
int number,time=0,i;//目标数字,出现次数,第一次出现的位置
printf("请输入你要查找的数字\n");
scanf("%d",&number);
LinkList pre;//用来遍历的指针
pre=head;
for(int j=0;pre!=NULL;j++)
{
if(pre->data==number)
{
if(time==0)
i=j; //第一次出现时的位置
time++;//每出现一次time都加一
}
pre=pre->next;
}
// 找完了
if(time==0) //如果该链表里没有出现过目标数字
{
printf("%d不存在此链表中",number);
return;
}else{
printf("%d在此链表中总共出现%d次,第一次出现在%d号位上\n",number,time,i);
}
}
//插入
void Insert(LinkList head)//这里传入的是表头的地址
{
int place;//目标位置
printf("请输入你想插入的位置:\n");
scanf("%d",&place);
//看看位置是否和合规范
if(place<=0||place>Length(head))
{
printf("位置违法!!%d\n",Length(head));
return;
}
LinkList pri,pre;
pre=(LinkList)malloc(sizeof(struct linklist));//先为要插入的数字申请空间
printf("请输入要插入的数据\n");
scanf("%d",&pre->data);
//找位置
pri=head;
for(int i=0;i<=place;i++)
{
if(i==place-1)//先找到目标位置的前一个节点
{
pre->next=pri->next;
pri->next=pre;
puts("插入成功!!");
break;
}
pri=pri->next;
}
}
//删除
void Delete(LinkList head)
{
int place;
LinkList pri,pre;
puts("请输入你想删除的位置:");
scanf("%d",&place);
if(place<0||place>Length (head))
{
printf("违规数字!!!\n");
return;
}
pre=head;
for(int i=0;i<=place;i++)
{
if(i==place-1)
{
pri=pre;
}
if(i==place)
{
pri->next=pre->next;
free(pre);
puts("删除完毕!!");
return;
}
pre=pre->next;
}
}
//输出
void OutList(LinkList head)
{
LinkList pre;
pre=head->next;
if(head->next==NULL) puts("该表为空表!!!!");
while(pre!=NULL)
{
printf("%d\n",pre->data);
pre=pre->next;
}
}
//清除
void ClearList(LinkList head)
{
LinkList pri,pre;
for(pre=head->next;pre!=NULL;pre=pri)
{
pri=pre->next;
free(pre);
}
head->next=NULL;
puts("链表清空完毕!!");
}
代码比较长,今天肝了一下午加一晚上,注释就后面在写了,让我先休息一下下。。。