发现大部分的文章对于链表的基本方法讲述很模糊,今天我为大家根据这个“通讯录”仔细讲解一下链表的的操作。

第一步:定义头文件

#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_); } } } }

以下为相关部分操作的图片:

c语言单链表的用法(C语音编写通讯录)(1)

c语言单链表的用法(C语音编写通讯录)(2)

c语言单链表的用法(C语音编写通讯录)(3)

以下为部分的代码段:(我在主函数里面借用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_); } } } }

,