c语言单链表的用法(C语音编写通讯录)
发现大部分的文章对于链表的基本方法讲述很模糊,今天我为大家根据这个“通讯录”仔细讲解一下链表的的操作。
第一步:定义头文件
#include<stdio.h>
#include<stdlib.h>
#include<io.h>
#include<windows.h> //清屏操作
#include<malloc.h> //动态分配内存
第二步:定义结构体指针变量
typedef struct Node
{
char id[30]; //用户ID
char name[30]; //用户姓名
char nex[10]; //用户性别
char number[30]; //用户电话号码
char birthday[30]; //用户生日
char address[30]; //用户家庭地址
struct Node *Next; //指针域
}Stu,*PStu;
结构体指针分为数据域和指针域,定义你所需要的相关变量。借用typedef进行一个改名字的操作,使得调用时候更加简洁方便,不易出错 !
本人比较喜欢把头节点单独用函数的方式写出来,这样调用比较方便
PStu createlist()
{
PStu headNode = (PStu)malloc(sizeof(Stu));
headNode -> Next = NULL;
return headNode;
}
动态的开辟内存空间,把头节点的下一个指向空指针,返回头节点的地址。
接下来就是几个基本操作
1.增添信息(头插法)
void addNode(PStu headNode)
{
PStu head = (PStu)malloc(sizeof(Stu));
printf("请输入ID:");
scanf("%s",head->id);
printf("请输入姓名:");
scanf("%s",head->name);
printf("请输入性别:");
scanf("%s",head->nex);
printf("请输入电话号码:");
scanf("%s",head->number);
printf("请输入生日:");
scanf("%s",head->birthday);
printf("请输入地址:");
scanf("%s",head->address);
head->Next = headNode->Next ;
headNode->Next = head;
}
尾插法
void endNode(PStu headNode)
{
PStu temp = headNode;
while(temp)
{
temp = temp ->Next ;
}
if(temp)
{
PStu s = (PStu)malloc(sizeof(Stu));
temp->Next = s;
temp = s;
printf("请输入ID:");
scanf("%s",s->id);
printf("请输入姓名:");
scanf("%s",s->name);
printf("请输入性别:");
scanf("%s",s->nex);
printf("请输入电话号码:");
scanf("%s",s->number);
printf("请输入生日:");
scanf("%s",s->birthday);
printf("请输入地址:");
scanf("%s",s->address);
temp ->Next = NULL;
}
}
这两种方法在我的上上篇文章中有详细讲解,不会的同学们可以去看看。
2.删除信息(借助姓名进行一个删除的操作)
void delectNode(PStu headNode,char *name)
{
PStu posNode = headNode->Next ;
PStu posfrontNode = headNode;
if(posNode == NULL)
{
printf("该链表为空");
return ;
}
else
{
while(strcmp(posNode->name,name))
{
posfrontNode = posNode;
posNode = posNode->Next;
if(posNode == NULL)
{
printf("不存在该数据,无法删除!");
return;
}
}
posfrontNode->Next = posNode->Next ;
free(posNode);
}
}
3.修改信息
首先根据自己的需要找到想要删除的位置(遍历链表),然后进行一个换值操作(char类型的要用strcpy进行赋值,int 类型用“=”进行一个赋值)
PStu gai(PStu headNode)
{
PStu p = headNode;
char address_[30];
char number_[20];
char id_[15];
char nex_[4];
int a,i;
char birthday_[20],name_[20];
printf("你想修改哪一位的相关信息:");
scanf("%d",&a);
getchar();
for(i = 1;i <= a;i ) //遍历链表
{
p = p->Next;
}
printf("请选择你要更改的信息 :\n");
printf("A.ID B.姓名 C.性别 D.电话号码 E.生日 F.地址 \n");
char w = getchar();
getchar();
if(w == 'A'||w == 'a')
{
int id;
printf("请输入修改后的ID:");
scanf("%s",id_);
getchar();
strcpy(p->id,id_);
}
if(w == 'B' || w == 'b')
{
printf("请输入修改后的姓名:");
scanf("%s",name_);
getchar();
strcpy(p->name,name_);
}
if(w == 'C'||w == 'c')
{
printf("请输入修改后的性别:");
scanf("%s",nex_);
strcpy(p->nex,nex_);
}
if(w == 'D'||w == 'd')
{
printf("请输入修改后的电话号码:");
scanf("%s",number_);
strcpy(p->number,number_);
}
if(w == 'E'||w == 'e')
{
printf("请输入修改后的生日:");
scanf("%s",birthday_);
strcpy(p->birthday,birthday_);
}
if(w == 'F'||w == 'f')
{
printf("请输入修改后的地址:");
scanf("%s",address_);
strcpy(p->address,address_);
}
return p;
}
这个代码段我可以修改任意一组信息,借助一个简单的if语句进行操作
4.查找信息
找到需要的信息,进行一个遍历操作,找到后可以返回这个节点的地址,从而得到这个地址所有的相关信息
PStu reviseNode(PStu headNode,char *id) //借助ID进行查找
{
PStu head = headNode;
while(head)
{
if(strcmp(head->id,id))
{
head = head->Next;
}
else
break;
}
return head;
}
5.遍历信息
把每一个节点的所有数据都进行一个输出,借用while遍历链表
void printList(PStu headNode)
{
PStu r = headNode->Next ;
while(r)
{
printf("%s %s %s %s %s %s\n",r->id ,r->name ,r->nex ,r->number ,r->birthday ,r->address );
r = r->Next;
}
}
6.排序信息(冒泡排序)
思路和方法和正常的数组排序一模一样,只是将for循环的条件改为链表的操作(char类型的要用strcpy进行赋值,int 类型用“=”进行一个赋值)
void maopao(PStu headNode)
{
PStu t;
PStu u;
char name_[30],id_[30],nex_[20],birthday_[30],number_[30],address_[30];
for(t = headNode->Next;t!= NULL;t = t->Next)
{
for(u = headNode->Next;u->Next != NULL;u = u->Next)
{
if(strcmp(u->id , u->Next->id)>0)
{
strcpy(id_,u->id);
strcpy(u->id,u->Next->id);
strcpy(u->Next->id,id_);
strcpy(name_,u->name);
strcpy(u->name,u->Next->name);
strcpy(u->Next->name,name_);
strcpy(nex_,u->nex);
strcpy(u->nex,u->Next->nex);
strcpy(u->Next->nex,nex_);
strcpy(number_,u->number);
strcpy(u->number,u->Next->number);
strcpy(u->Next->number,number_);
strcpy(birthday_,u->birthday);
strcpy(u->birthday,u->Next->birthday);
strcpy(u->Next->birthday,birthday_);
strcpy(address_,u->address);
strcpy(u->address,u->Next->address);
strcpy(u->Next->address,address_);
}
}
}
}
以下为相关部分操作的图片:
以下为部分的代码段:(我在主函数里面借用do-while循环进行循环操作,通过break进行退出循环)
#include<stdio.h>
#include<stdlib.h>
#include<io.h>
#include<windows.h>
#include<malloc.h>
typedef struct Node
{
char id[30]; //用户ID
char name[30]; //用户姓名
char nex[10]; //用户性别
char number[30]; //用户电话号码
char birthday[30]; //用户生日
char address[30]; //用户家庭地址
struct Node *Next; //指针域
}Stu,*PStu;
void menu()
{
printf("\n\t--------小艾通讯录-------");
printf("\n\t\t1.增添信息");
printf("\n\t\t2.删除信息");
printf("\n\t\t3.查找信息");
printf("\n\t\t4.修改信息");
printf("\n\t\t5.显示信息");
printf("\n\t\t6.排序信息"); //借助ID进行排序
printf("\n\t\t7.退出系统");
}
PStu createlist()
{
PStu headNode = (PStu)malloc(sizeof(Stu));
headNode -> Next = NULL;
return headNode;
}
void addNode(PStu headNode)
{
PStu head = (PStu)malloc(sizeof(Stu));
printf("请输入ID:");
scanf("%s",head->id);
printf("请输入姓名:");
scanf("%s",head->name);
printf("请输入性别:");
scanf("%s",head->nex);
printf("请输入电话号码:");
scanf("%s",head->number);
printf("请输入生日:");
scanf("%s",head->birthday);
printf("请输入地址:");
scanf("%s",head->address);
head->Next = headNode->Next ;
headNode->Next = head;
}
void endNode(PStu headNode)
{
PStu temp = headNode;
while(temp)
{
temp = temp ->Next ;
}
if(temp)
{
PStu s = (PStu)malloc(sizeof(Stu));
temp->Next = s;
temp = s;
printf("请输入ID:");
scanf("%s",s->id);
printf("请输入姓名:");
scanf("%s",s->name);
printf("请输入性别:");
scanf("%s",s->nex);
printf("请输入电话号码:");
scanf("%s",s->number);
printf("请输入生日:");
scanf("%s",s->birthday);
printf("请输入地址:");
scanf("%s",s->address);
temp ->Next = NULL;
}
}
void printList(PStu headNode)
{
PStu r = headNode->Next ;
while(r)
{
printf("%s %s %s %s %s %s\n",r->id ,r->name ,r->nex ,r->number ,r->birthday ,r->address );
r = r->Next;
}
}
void delectNode(PStu headNode,char *name)
{
PStu posNode = headNode->Next ;
PStu posfrontNode = headNode;
if(posNode == NULL)
{
printf("该链表为空");
return ;
}
else
{
while(strcmp(posNode->name,name))
{
posfrontNode = posNode;
posNode = posNode->Next;
if(posNode == NULL)
{
printf("不存在该数据,无法删除!");
return;
}
}
posfrontNode->Next = posNode->Next ;
free(posNode);
}
}
PStu reviseNode(PStu headNode,char *id)
{
PStu head = headNode;
while(head)
{
if(strcmp(head->id,id))
{
head = head->Next;
}
else
break;
}
return head;
}
PStu gai(PStu headNode)
{
PStu p = headNode;
char address_[30];
char number_[20];
char id_[15];
char nex_[4];
int a,i;
char birthday_[20],name_[20];
printf("你想修改哪一位的相关信息:");
scanf("%d",&a);
getchar();
for(i = 1;i <= a;i )
{
p = p->Next;
}
printf("请选择你要更改的信息 :\n");
printf("A.ID B.姓名 C.性别 D.电话号码 E.生日 F.地址 \n");
//getchar();
char w = getchar();
getchar();
if(w == 'A'||w == 'a')
{
int id;
printf("请输入修改后的ID:");
scanf("%s",id_);
getchar();
strcpy(p->id,id_);
}
if(w == 'B' || w == 'b')
{
printf("请输入修改后的姓名:");
scanf("%s",name_);
getchar();
strcpy(p->name,name_);
}
if(w == 'C'||w == 'c')
{
printf("请输入修改后的性别:");
scanf("%s",nex_);
strcpy(p->nex,nex_);
}
if(w == 'D'||w == 'd')
{
printf("请输入修改后的电话号码:");
scanf("%s",number_);
strcpy(p->number,number_);
}
if(w == 'E'||w == 'e')
{
printf("请输入修改后的生日:");
scanf("%s",birthday_);
strcpy(p->birthday,birthday_);
}
if(w == 'F'||w == 'f')
{
printf("请输入修改后的地址:");
scanf("%s",address_);
strcpy(p->address,address_);
}
return p;
}
void maopao(PStu headNode)
{
PStu t;
PStu u;
char name_[30],id_[30],nex_[20],birthday_[30],number_[30],address_[30];
for(t = headNode->Next;t!= NULL;t = t->Next)
{
for(u = headNode->Next;u->Next != NULL;u = u->Next)
{
if(strcmp(u->id , u->Next->id)>0)
{
strcpy(id_,u->id);
strcpy(u->id,u->Next->id);
strcpy(u->Next->id,id_);
strcpy(name_,u->name);
strcpy(u->name,u->Next->name);
strcpy(u->Next->name,name_);
strcpy(nex_,u->nex);
strcpy(u->nex,u->Next->nex);
strcpy(u->Next->nex,nex_);
strcpy(number_,u->number);
strcpy(u->number,u->Next->number);
strcpy(u->Next->number,number_);
strcpy(birthday_,u->birthday);
strcpy(u->birthday,u->Next->birthday);
strcpy(u->Next->birthday,birthday_);
strcpy(address_,u->address);
strcpy(u->address,u->Next->address);
strcpy(u->Next->address,address_);
}
}
}
}
免责声明:本文仅代表文章作者的个人观点,与本站无关。其原创性、真实性以及文中陈述文字和内容未经本站证实,对本文以及其中全部或者部分内容文字的真实性、完整性和原创性本站不作任何保证或承诺,请读者仅作参考,并自行核实相关内容。文章投诉邮箱:anhduc.ph@yahoo.com