IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> 数据结构与算法 -> 预备役13(2021.12.08) -> 正文阅读

[数据结构与算法]预备役13(2021.12.08)

最近一直在码项目。直到今天,终于正式的完成了一个属于自己的第一个项目。虽然可能有些不足,有些地方确实也需要修改,但是大体功能是实现了的,对我来说也是一个挑战和突破,再写的过程中,我也逐渐认清楚自己是要走项目还是要走算法的道路。下面我就对于这次项目做一个总结。

这一次我写了一个简单的通讯录。其核心就是链表和对文件的处理。可能有些功能并不完善,如果有好的建议,请写在评论区,我会及时修改或者改进。刚开始我对于链表并不熟悉,只能说看得懂但远远没到会用,会写的程度。于是我只能边学边写,进度很缓慢。

首先是主程序:

int x;

? ? link();//把文件内容导入链表

? ? menu();//打印菜单

? ? printf("请输入你的选择\n");

? ? scanf("%d", &x);

? ? while (x)

? ? {

? ? ? ? switch (x)

? ? ? ? {

? ? ? ? case 1:

? ? ? ? ? ? add();

? ? ? ? ? ? break;

? ? ? ? case 2:

? ? ? ? ? ? del();

? ? ? ? ? ? break;

? ? ? ? case 3:

? ? ? ? ? ? update();

? ? ? ? ? ? break;

? ? ? ? case 4:

? ? ? ? ? ? search();

? ? ? ? ? ? break;

? ? ? ? case 5:

? ? ? ? ? ? save();

? ? ? ? ? ? break;

? ? ? ? case 6:

? ? ? ? ? ? display();

? ? ? ? ? ? break;

? ? ? ? case 7:

? ? ? ? ? ? delall();

? ? ? ? ? ? break;

? ? ? ? case 8:

? ? ? ? ? ? Count();

? ? ? ? ? ? break;

? ? ? ? default:

? ? ? ? ? ? printf("输入错误,请重新输入!");

? ? ? ? ? ? break;

? ? ? ? }

? ? ? ? menu();

? ? ? ? scanf("%d", &x);

? ? ? ? if (x == 0)

? ? ? ? {

? ? ? ? ? ? break;

? ? ? ? }

? ? }

这里我写了一个link函数,因为我要对文件里边的内容进行导入到链表。所以在程序执行前会调用它,后面没什么好说的,就是简单的用switch来调用不同函数功能。

接着是第一个功能,添加联系人,先上代码:

void add()

{

? ? char s;

? ? while (1)

? ? {

? ? ? ? p1 = (struct node *)malloc(LEN);

? ? ? ? p2->next = p1;

? ? ? ? p2 = p1;

? ? ? ? printf("请输入联系人姓名:");

? ? ? ? scanf("%s", p2->content.name);

? ? ? ? printf("请输入联系人地址:");

? ? ? ? scanf("%s", p2->content.adress);

? ? ? ? printf("请输入联系人电话号码:");

? ? ? ? scanf("%s", p2->content.number);

? ? ? ? printf("请输入联系人邮箱:");

? ? ? ? scanf("%s", p2->content.email);

? ? ? ? getchar();

? ? ? ? printf("添加联系人成功!\n你是否想继续存储?(Y ?or ?N):");

? ? ? ? scanf("%c", &s);

? ? ? ? if (s == 'Y')

? ? ? ? ? ? continue;

? ? ? ? else

? ? ? ? ? ? break;

? ? }

? ? p2->next = NULL;

? ? printf("\n");

}

这里因为我先调用了link函数把文件里面的内容导入链表,所以现在我就不需要再一次创建链表,只需要在节点后面继续开辟新空间就行。这里我当时因为找不准节点的接入,一直出错,debug好久。。。。。

然后就是删除联系人:

void del()

{

? ? char m[100];

? ? char k;

? ? p = q = head;

? ? printf("请输入你想要删除的联系人姓名:");

? ? scanf("%s", m);

? ? getchar();

? ? struct node *h = head;

? ? while (q != NULL)

? ? {

? ? ? ? if (strcmp(q->content.name, m) == 0 && q == head)

? ? ? ? {

? ? ? ? ? ? head = head->next;

? ? ? ? ? ? printf("删除成功!\n");

? ? ? ? }

? ? ? ? else if (strcmp(q->content.name, m) == 0)

? ? ? ? {

? ? ? ? ? ? p->next = q->next;

? ? ? ? ? ? free(q);

? ? ? ? ? ? printf("删除成功!\n");

? ? ? ? }

? ? ? ? else

? ? ? ? {

? ? ? ? ? ? p = q;

? ? ? ? ? ? q = q->next;

? ? ? ? ? ? continue;

? ? ? ? }

? ? ? ? printf("你是否要继续删除?\n继续输入'Y'否则输入'N':");

? ? ? ? scanf("%c", &k);

? ? ? ? getchar();

? ? ? ? if (k == 'Y')

? ? ? ? {

? ? ? ? ? ? printf("请输入你想要删除的联系人姓名:");

? ? ? ? ? ? scanf("%s", m);

? ? ? ? ? ? getchar();

? ? ? ? ? ? q = p = head;

? ? ? ? ? ? continue;

? ? ? ? }

? ? ? ? else if (k == 'N')

? ? ? ? ? ? break;

? ? }

}

这个就很简单了,就是对链表进行删除,就是对链表进行遍历,找出我们先要删除的联系人,如果是第一个节点,我们就让头指针往下移一个。如果不是,我们就用双指针进行删除。

下一个是修改联系人:

void update()

{

? ? char k;

? ? p2 = p1 = head;

? ? char m[100], n[100];

? ? if (head == NULL)

? ? ? ? printf("通讯录中无可修改的联系人!\n");

? ? while (p1 != NULL)

? ? {

? ? ? ? printf("请输入你想修改的联系人名字:");

? ? ? ? scanf("%s", m);

? ? ? ? getchar();

? ? ? ? if (strcmp(p1->content.name, m) == 0)

? ? ? ? {

? ? ? ? ? ? printf("请输入联系人新的姓名:");

? ? ? ? ? ? scanf("%s", p1->content.name);

? ? ? ? ? ? printf("请输入联系人新的地址:");

? ? ? ? ? ? scanf("%s", p1->content.adress);

? ? ? ? ? ? printf("请输入联系人新的电话:");

? ? ? ? ? ? scanf("%s", p1->content.number);

? ? ? ? ? ? printf("请输入联系人新的邮箱:");

? ? ? ? ? ? scanf("%s", p1->content.email);

? ? ? ? ? ? printf("修改成功!");

? ? ? ? ? ? p1 = head;

? ? ? ? }

? ? ? ? else

? ? ? ? {

? ? ? ? ? ? p1 = p1->next;

? ? ? ? ? ? continue;

? ? ? ? }

? ? ? ? getchar();

? ? ? ? printf("你是否想继续修改?继续输入'Y'否则输入'N':");

? ? ? ? scanf("%c", &k);

? ? ? ? if (k == 'Y')

? ? ? ? ? ? continue;

? ? ? ? else if (k == 'N')

? ? ? ? ? ? break;

? ? }

}

修改联系人,就是对结构体进行重新赋值,这个没什么可说的。

接着是查找联系人:

void search()

{

? ? char m[100], k;

? ? p1 = head;

? ? printf("请输入你想要查询的联系人姓名 ?:");

? ? scanf("%s", m);

? ? getchar();

? ? if (head == NULL)

? ? ? ? printf("通讯录中无可查询的联系人!\n");

? ? while (p1 != NULL)

? ? {

? ? ? ? if (strcmp(p1->content.name, m) == 0)

? ? ? ? ? ? Printf(m);

? ? ? ? else

? ? ? ? {

? ? ? ? ? ? p1 = p1->next;

? ? ? ? ? ? continue;

? ? ? ? }

? ? ? ? printf("你想继续查询联系人吗?\n继续输入'Y'否则输入'N':");

? ? ? ? scanf("%c", &k);

? ? ? ? getchar();

? ? ? ? if (k == 'Y')

? ? ? ? {

? ? ? ? ? ? p1 = head;

? ? ? ? ? ? printf("请输入你想查询的联系人姓名:");

? ? ? ? ? ? scanf("%s,m");

? ? ? ? ? ? continue;

? ? ? ? }

? ? ? ? else if (k == 'N')

? ? ? ? ? ? break;

? ? }

}

这里我用了一个函数进行封装,每次只需要在链表中找到对应联系人,在调用函数就行了。

还有就是存储数据,也就是把链表内容导入文件:

void save()

{

? ? q = head;

? ? FILE *fp = fopen("C:\\Users\\JY\\Desktop\\通讯录.txt", "w+");

//这里要把打开文件改成自己电脑里的路径!

? ? while (q != NULL)

? ? {

? ? ? ? fprintf(fp, "%s\n", q->content.name);

? ? ? ? fprintf(fp, "%s\n", q->content.adress);

? ? ? ? fprintf(fp, "%s\n", q->content.number);

? ? ? ? fprintf(fp, "%s\n", q->content.email);

? ? ? ? q = q->next;

? ? }

? ? printf("保存成功!\n");

? ? fclose(fp);

}

因为刚学的C,对于文件这一块可以说是完全不懂,甚至没接触过,只知道这里一个小小的w+,让我找了三天没找来,还差点把代码修改炸了。其实文件会用也不难,如果要涉及底层原理,比如说是如何把文本文件与程序进行互相导入导出,如何导入到二进制文件中,以及缓冲区和输出流等等的原理,要理解起来是要费点时间的。因为时间紧迫,我就没能一一深入了解。总归来说,FILE* fp=fopen(“文件路径”,“打开方式”)是打开文件的必要条件,结束之后要记得关闭文件,但是好像程序结束也能关闭。

最后一个就是打印链表。这个也挺简单的:

void display()

{

? ? p1 = head;

? ? if (head == NULL)

? ? ? ? printf("此文件中无联系人!\n");

? ? else

? ? {

? ? ? ? while (p1 != NULL)

? ? ? ? {

? ? ? ? ? ? printf("=============================\n");

? ? ? ? ? ? printf("姓名:%s\t", p1->content.name);

? ? ? ? ? ? printf("地址:%s\t", p1->content.adress);

? ? ? ? ? ? printf("电话号码:%s\t", p1->content.number);

? ? ? ? ? ? printf("电子邮箱:%s\t\n", p1->content.email);

? ? ? ? ? ? printf("=============================\n");

? ? ? ? ? ? p1 = p1->next;

? ? ? ? ? ? printf("\n");

? ? ? ? }

? ? }

? ? printf("\n");

}

这里没什么好说的,完全就是对链表进行打印。

对于这一次的项目,我深深的感受到了什么叫做debug的痛苦,因为对与链表和文件的不熟练,导致我花费在改代码的时间比我写代码的时间还要长,让我一度很痛苦,不过好在今天终于把bug全部改完了。就希望自己以后能多注意点细节处理,然后把底层原理给弄懂,这样处理代码的时候就能够简单一些吧。

  数据结构与算法 最新文章
【力扣106】 从中序与后续遍历序列构造二叉
leetcode 322 零钱兑换
哈希的应用:海量数据处理
动态规划|最短Hamilton路径
华为机试_HJ41 称砝码【中等】【menset】【
【C与数据结构】——寒假提高每日练习Day1
基础算法——堆排序
2023王道数据结构线性表--单链表课后习题部
LeetCode 之 反转链表的一部分
【题解】lintcode必刷50题<有效的括号序列
上一篇文章      下一篇文章      查看所有文章
加:2021-12-09 11:55:23  更:2021-12-09 11:57:28 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2025年1日历 -2025/1/10 2:12:31-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码