数据结构之单链表


title: 数据结构之单链表
copyright: true
date: 2018-09-12 14:34:18
tags: 数据结构
categories: 数据结构

从今天起开始数据结构系列的分享,今天分享的是单链表。单链表大概是大概是每个数据结构
初学者的必经之路,下面结合一个小小的工程深入学习单链表的使用–简易客户管理系统。
ps:如果还不清楚单链表是什么的小伙伴自行百度,在此不在赘述


#项目结构
增删改查,增、删、改这三个部分同时包含了将变动后的信息写入到文件中的操作


#代码编写
##项目基础代码
俗话说得好,“万丈高楼平地起”,先来编写项目的预定义代码部分,主要是头文件
包含、结构体定义、全局变量定义等
###头文件包含
#include<stdio.h> //C程序基础库
#include<stdlib.h> //包含函数exit()
#include<string.h> //包含函数strcmp()
###结构体定义

typedef struct item{	
	char name[20];    //保存客户姓名   
	char gender[20];  //保存客户性别 
	int  age;         //保存客户年龄 
	char tel[20];     //保存客户号码 
} guest;

结构体定义不要多说了哈,这里typedef...guest是给结构体item起别名的意思,也就是
struct item在这个源文件里面等价于guest

typedef struct node {
	guest data;         //数据域 
	struct node * next; //指针域 
}* link;

这里是给指向结构体node的指针起别名
###全局变量定义
link T;//头指针
这个头指针T是整个系统的索引,六个模块共有一个,虽然有尽量少定义全局变量的原则,但这里
的全局变量T可以避免各个函数间复杂的参数传递问题,牺牲了空间,换取了运行时间的减少;
同时要注意我在后面对T的初始化代码

//初始化头指针
T=(link)malloc(sizeof(struct node));
T->next = NULL;

这里并没有给T安排数据域,T不是第一个存储客户信息的节点指针,T->next才是,初始化头指针
时还没有存储客户信息的结点加入,所以T->next=NULL;,这是一个编程者应该养成的好习惯;为
什么不给T安排数据域呢,这里主要考虑到后面的删除模块的编写,我们知道,删除一个结点,要先
找到这个结点的前驱指针p和后驱指针q,然后p->next = q->next;,如果给T安排数据域的话,
T的前驱是什么呢?就算不用上面我说的那套删除逻辑,用if...else...语句和另外一套逻辑
完成对T的删除,代码明显复杂些。
##项目核心代码
###一、加载文件
代码如下

void init() {
	link p,s;
	FILE *fp;
	int i  = 0;
	s = p=(link)malloc(sizeof(struct node));
	p->next = NULL;
	if((fp=fopen("1.txt","r"))==NULL) {
		printf("load error!");
		exit(1);
	}
	while(!feof(fp)) {
		fscanf(fp,"%s\t%s\t%d\t%s\t\n",p->data.name,p->data.gender,&p->data.age,p->data.tel);
		i++;
		if(i!=1) {
			s->next = p;
			s=p;
		}
		else{
			T->next = p;
		}
		p=(link)malloc(sizeof(struct node));
		p->next = NULL;
	}
	printf("总人数i=====%d\n",i);
	if(fclose(fp)) {
		printf("Can't close the file!\n");
		exit(1);
	}
}

介绍下代码逻辑,新开辟内存空间,并使s、p指向它,打开文件,如果文件指针没有到文件尾,将
从文件读取到的一个客户信息赋给p的数据域,如果是读取第一个客户信息,将p指向的结点连在头
指针T后面,否则,将p连在s后面,因为这个时候s是p的前驱指针,连接成功后将p赋值给s,p又
指向一个新开辟的结点…

###二、增加客户
代码如下:

//添加
void create() {
	link p,s;
	FILE *fp;
	int yn;
	s=T;
	while(s->next!=NULL) {
		s=s->next;
	}
	do {
		p=(link)malloc(sizeof(struct node));
		printf("请输入客户姓名:\n");
		scanf("%s",p->data.name);
		printf("请输入客户性别:\n");
		scanf("%s",p->data.gender);
		printf("请输入客户年龄:\n");
		scanf("%d",&p->data.age);
		printf("请输入客户联系方式:\n");
		scanf("%s",p->data.tel);
		p->next=NULL;
		s->next=p;
		s=p;
		if((fp=fopen("1.txt","at"))==NULL) {
			printf("write error!\n");
			exit(0);
		}
		printf("写了一次\n");
		fprintf(fp,"%s\t%s\t%d\t%s\n",p->data.name,p->data.gender,p->data.age,p->data.tel);
		if(fclose(fp)) {
			printf("can't close the file!\n");
			exit(0);
		}
		printf("添加成功!\n");
		printf("是否继续添加请输入0或1:");
		scanf("%d",&yn);
	} while(yn);
}

代码逻辑很简单,新增结点,并连在尾节点后面,同时写入文件,如果前一片代码看懂了,这不是什么
大问题…
###三、删除客户
代码如下

//删除
int del() {
	link p,q;
	FILE *fp;
	char mod[25];
	printf("请输入需要删除的客户名称:\n");
	scanf("%s",mod);
	p=T;
	while(p->next!=NULL&&strcmp(p->next->data.name,mod)!=0)
		p=p->next;
	if(p->next==NULL) {
		printf("并无此人!\n");
		return 0;
	}
	q = p;
	p = p->next;
	q->next = p->next; 
	delete(p);
	printf("删除成功!\n");
	if((fp=fopen("1.txt","wt"))==NULL) {
		printf("error!\n");
		exit(0);
	}
	p=T->next;
	while(p!=NULL) {
		printf("%s",p->data.name);
		fprintf(fp,"%s\t%s\t%d\t%s\t\n",p->data.name,p->data.gender,p->data.age,p->data.tel);
		p = p->next; 
	}
	if(fclose(fp)) {
		printf("can't close the file!\n");
		exit(1);
	}
}

模块三、四、五、六道理类似,不再赘述
附上代码地址:
github 欢迎star
如有疑问,欢迎进群讨论:
数据结构与算法交流群

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

月小水长

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值