PS:感谢3位室友:姚周/大佬、永琪/小哥和高老板在我思路卡壳的时候提供的帮助!
前言:
0.建议使用电脑查看本日志,手机查看可能排版会乱掉。
1.修仙修到将近凌晨3点写的代码。基本是在自己理解的情况下不看书写出来的(除了插入和删除还是不太理解,瞄了一眼参考代码)。
2.因为之前问的人有点多,所以直接发在QQ空间供大家参考。如果有错误或不当的地方欢迎大家指正!
3.送给大家一句话:“天下代码一大抄,看你会抄不会抄。”希望大家在借鉴的情况下有所创新!
4.初学者刚开始写代码,几乎都是从模仿开始的,刚开始模仿并不丢人,丢人的是模仿后不去学习消化。
修改日志:
18年10月8日 18:12 修复了删除第i个结点,结果删除了第(i+1)个结点的BUG
具体措施:修改原语句for(j=2;j<=i;j++)为现语句for(j=2;j<i;j++)
#include<stdio.h>
#include<malloc.h>
typedef int ElemType;
typedef struct Node
{
ElemType data;
struct Node *next;
}LNode,*PtrToList,*LinkedList;
/*函数声明模块*/
LinkedList New(LinkedList head);
LinkedList Insert(LinkedList head,int i,int x);
LinkedList DelKth(LinkedList head,int i);
int Length(LinkedList head);
int FindKey(LinkedList head,int key);
void Print(LinkedList head);
int Clear(LinkedList head);
int main(void)
{
int command;
LinkedList LL1;
PtrToList head;
int key;
int position;
int succeed;
int count1=0;
int insPosition;
int insX;
int delPosition;
printf("欢迎使用链表示例程序!\n");
printf("请按照指令集进行操作或输入0退出:\n");
printf("注意:请务必使用指令1新建链表后再使用指令2~7!\n");
do
{
printf("指令1:新建链表并输出\n");
printf("指令2:在链表第i个结点后插入一个数据并输出\n");
printf("指令3:删除链表中的第i个结点并输出\n");
printf("指令4:求链表的表长\n");
printf("指令5:查找给定值第一次在链表中出现的位置\n");
printf("指令6:输出当前链表\n");
printf("指令7:清空当前链表\n");
printf("输入0:退出\n");
do
{
scanf("%d",&command);
}
while(command<0||command>7);
if(count1==0&&command!=1)
printf("在使用指令N新建链表前禁止使用指令2~7!\n");
if(command==1)
count1++;
switch(command)
{
case 0:
printf("Made by TGldm_666\n");
printf("感谢使用,祝您生活愉快!\n");
return 0;
break;
case 1:
LL1=New(head);
head=LL1;
Print(LL1);
break;
case 2:
printf("请输入要插入数据的位置:");
scanf("%d",&insPosition);
printf("请输入要插入的数据:");
scanf("%d",&insX);
LL1=Insert(head,insPosition,insX);
head=LL1;
Print(LL1);
break;
case 3:
printf("请输入要删除数据的位置:");
scanf("%d",&delPosition);
LL1=DelKth(head,delPosition);
head=LL1;
Print(LL1);
break;
case 4:
printf("链表的表长是:%d\n",Length(LL1));
break;
case 5:
printf("请输入要查找的Key值:\n");
scanf("%d",&key);
position=FindKey(LL1,key);
if(position!=-1)
printf("该数第一次出现在链表中的第%d个位置\n",position);
else
printf("查无此数\n");
break;
case 6:
Print(LL1);
break;
case 7:
succeed=Clear(LL1);
printf("清除单链表成功!\n");
break;
}
printf("请继续操作或按0退出:\n");
}
while(command!=0);
return 0;
}
/*指令1:新建链表并输出*/
LinkedList New(LinkedList head)
{
LinkedList p,q,h=NULL;
ElemType x;
int count=0;
printf("请输入正整数作为链表元素(输入0来结束输入):\n");
scanf("%d",&x);
p=(LinkedList)malloc(sizeof(LNode));
p->data=x;
p->next=NULL;
while(x!=0)
{
count++;
if(count==1)
q=h=p;
else
{
q->next=p;
q=p;
}
scanf("%d",&x);
p=(LinkedList)malloc(sizeof(LNode));
p->data=x;
p->next=NULL;
}
return h;
}
/*指令2:在链表第i个结点后插入一个数据并输出*/
LinkedList Insert(LinkedList head,int i,int x)
{
if(i<1)
{
printf("请输入正确的插入位置!\n");
return head;
}
PtrToList p,q;
int j;
p=(LinkedList)malloc(sizeof(LNode));
p->data=x;
if(i==0)
{
p->next=head;
head=p;
}
else
{
q=head;
j=1;
while(j<i&&q!=NULL)
{
j++;
q=q->next;
}
}
if(q!=NULL)
{
p->next=q->next;
q->next=p;
printf("插入数据成功!\n");
}
else
printf("请输入正确的插入位置!\n");
return head;
}
/*指令3:删除链表中的第i个结点并输出*/
LinkedList DelKth(LinkedList head,int i)
{
PtrToList p,temp;
int j;
p=head->next;
if(i<1)
{
printf("请输入正确的删除位置!\n");
return head;
}
temp=head;
for(j=2;j<i;j++)
{
if(p!=NULL)
{
p=p->next;
temp=temp->next;
}
else
break;
}
if(p==NULL)
{
printf("请输入正确的删除位置!\n");
return head;
}
temp->next=p->next;
free(p);
printf("删除成功!\n");
return head;
}
/*指令4:求链表的表长*/
int Length(LinkedList head)
{
PtrToList p=head;
int count=0;
while(p!=NULL)
{
count++;
p=p->next;
}
return count;
}
/*指令5:查找给定值第一次在链表中出现的位置*/
int FindKey(LinkedList head,int key)
{
PtrToList p;
p=head;
int position=1;
while(p->data!=key&&p!=NULL)
{
p=p->next;
position++;
}
if(p!=NULL)
return position;
else
return -1;
}
/*指令6:输出当前链表*/
void Print(LinkedList head)
{
PtrToList p=head;
int count=0;
printf("当前链表如下:\n");
while(p!=NULL)
{
count++;
printf("第%d个元素:%d\n",count,p->data);
p=p->next;
}
printf("\n");
}
/*指令7:清空当前链表*/
int Clear(LinkedList head)
{
PtrToList p;
while(head->next!=NULL)
{
p=head->next;
head->next=head->next->next;
free(p);
}
return 1;
}