#include<stdio.h>
#include<malloc.h>
#include<conio.h>
#define OK 1
#define ERROR -1
#define OVERFLOW -2
#define ENDFLAG 0
typedef struct LNode{
int data;
LNode *next;
}LNode;//定义链表结点
//初始化链表
int InitSqList(LNode *head){
head=(LNode *)malloc(sizeof(LNode));//定义头结点
if(NULL== head)
exit(ERROR);//-1 初始化失败
head->next=NULL;//初始化成功
return OK;//1
}
//判空
int ListEmpty(LNode *head){
if(NULL==head->next)
return OK;
return ENDFLAG;//0不为空
}
//尾插法插入
int Create_List_Tail(LNode *head,int n){
int i,temp;
LNode *p,*q=head;//辅助指针q始终指向表尾
if(n<=0)
exit(ERROR);//-1
printf("请输入你的数据: ");
for(i=1;i<=n;i++){
p=(LNode *)malloc(sizeof(LNode));
scanf("%d",&temp);
p->data=temp;
p->next=NULL;
q->next=p;//将新的节点插入到表尾
q=p;//辅助指针q指向新的表尾
}
return OK;//1 创建成功
}
int LocateElem(LNode *head,int e){
//查找数据元素的位置 {
int count = 1;
LNode *p=head->next;
while(NULL!=p&&p->data!=e){
p=p->next;count++;
}
if(NULL==p)
{
printf("该元素不存在!按任意键退出:");
getch();
exit(ENDFLAG);//0
}
printf("%d\n",count);
return OK;
}
//插入
int ListInsert(LNode *head,int i,int e){
int count=0;//count 始终为p节点的位序
LNode *p=head,*q=NULL;
while(count<i-1&&NULL!=p){//寻找第i-1个结点
p=p->next;count++;
}
q=(LNode *)malloc(sizeof(LNode));
if(NULL==q)
exit(OVERFLOW);//-2 因为存储分配失败导致插入操作失败
q->data=e;
q->next=p->next;
p->next=q;
return OK;//1 插入成功
}
//删除
int DeletLinkList(LNode *head,int i){
int count=0;//count始终为P结点的位序
LNode *p=head,*q=NULL;
while(count<i-1&&NULL!=p){//找第i-1个结点,并保证第i个结点存在
p=p->next;count++;
}
q=p->next;//让指针q指向要删除的第i个结点
p->next=q->next;//删除
free(q);//释放空间
return OK;//1
//删除成功
}
//求长度
int LinkList_Length(LNode *head){
int len=0;
LNode *p=head->next;
while(NULL!=p){
len++;p=p->next;
}
return len;
}
//显示
int ShowLinkList(LNode *head){
LNode *p=head->next,*q=head->next;
while(NULL!=p){
if(q->next==NULL)
printf("%d\n",p->data);
else
printf("%d ",p->data);
p=p->next;
q=p;
}
}
int main(){
LNode L;
int i,e,l,n,num;
if(!InitSqList(&L)){
printf("初始化失败,按任意键退出:");
getch();
exit(0);
}
printf("请输入你要输入的个数:");
scanf("%d",&n);
if(!Create_List_Tail(&L,n)){
printf("赋值失败按任意键退出:");
getch();
exit(0);
}
ShowLinkList(&L);
printf("是否执行插入操作?1-是\n");
printf("请输入你的选择:");
int j,k,m;
scanf("%d",&j);
if(j==1)
goto insert;
else
goto delet;
insert:
printf("请输入你要插入的位置:");
scanf("%d",&i);
if(i<=0||i>(LinkList_Length(&L)))
exit(ERROR);//-1插入位置不对?:退出,继续
printf("请输入你要插入的数:\n");
scanf("%d",&e);
if(!ListInsert(&L,i,e)){
printf("插入失败按任意键退出:");
getch();
exit(0);
}
ShowLinkList(&L);
delet:
printf("\n是否实现删除操作?1-是\n");
printf("请输入你的选择:");
scanf("%d",&k);
if(k==1)
goto yes;
else
exit(0);
yes:
if(1==ListEmpty(&L))//判空
exit(ERROR);//-1
printf("请输入你要删除的数的位置:");
scanf("%d",&l);
if(l<=0||l>(LinkList_Length(&L)))
exit(OVERFLOW);//-2插入位置不对则退出
if(!DeletLinkList(&L,l)){
printf("删除失败按任意键退出:\n");
getch();
exit(0);
}
ShowLinkList(&L);
printf("是否执行查找元素位置操作?1-是\n");
printf("请输入你的选择:");
scanf("%d",&m);
if(m==1)
goto locate;
else
exit(0);
locate:
printf("请输入你要查找的元素的值:");
scanf("%d",&num);
if(!LocateElem(&L,num)){
printf("查找失败按任意键返回:");
getch();
exit(0);
}
printf("单链表基本操作测试已经结束,按任意键退出:\n");
getch();
return 0;
}
/*
对链表的这些操作 如果是增加或者删除 如果是直接用指针作为参数传递
将会是值传递 对于参数的修改不会改变原来的链表
解决方法有两种
一个是修改参数以后返回函数参数 赋给原来main函数里面的指针
或者通过二级指针 也就是传递main函数里面的指针的地址 这样就是地址传递可以修改链表成功
*/