不多说,直接上马,一个水果实例:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
//这是跳过警告,在vs编译器中使用,需加上词句
#pragma warning(disable:4996)
#define WHILE_ONE 1
struct fruit
{
char name[20];
double price;
};
struct fruitLink
{
struct fruit data;//值域
struct fruitLink *next;//指针域
};
下为函数声明
//1.0创建新节点
struct fruitLink * CreateNewNode(struct fruit data);
//2.0判断头节点是不是NULL,是NULL-0,非NULL-1
int isNullHeadNode(struct fruitLink *head);
//3.0后插法
void Insert_After(struct fruitLink *head, struct fruit data);
//4.0打印链表数据
void Print_Link(struct fruitLink * head);
//5.0根据水果姓名查找
struct fruitLink *Find_Name(struct fruitLink * head, char * name);
//6.0获取新增的水果,然后调用后插法
void Add_Fruit(struct fruitLink * head);
//7.0菜单
void Printf_Menu();
//8.0获取删除水果名称
void Del_Fruit(struct fruitLink *head);
//9.0删除水果
void Del_Name(struct fruitLink * head, char* name);
//10.0按水果价格降序排序
void Sort_Fruit_Price(struct fruitLink *head);
//11.0修改水果价格
void Modify_Fruit_Price(struct fruitLink *head);
//12.0保存到txt
void Save(struct fruitLink* head);
//13.0从txt中读取数据到链表
void Load(struct fruitLink* head);
//14.0销毁链表
void FreeAll(struct fruitLink* head);
主函数
int main()
{
struct fruitLink * head = NULL;
int choose = -1;
//为头结点申请空间
head = calloc(1, sizeof(struct fruitLink));
head->next = NULL;
while (WHILE_ONE)
{
//printf("****请选择****\n");
Printf_Menu();
scanf("%d", &choose);
while (getchar() != '\n');
switch (choose)
{
case 1://添加水果
Add_Fruit(head);
break;
case 2://删除水果
Del_Fruit(head);
break;
case 3://按水果价格排序
Sort_Fruit_Price(head);
break;
case 4://修改水果价格
Modify_Fruit_Price(head);
break;
case 5://打印
Print_Link(head);
break;
case 6://保存
Save(head);
break;
case 7://加载
Load(head);
break;
case 0://退出
Save(head);
FreeAll(head);
return 0;
default:
printf("选择错误!!\n");
break;
}
}
return 0;
}
菜单
void Printf_Menu()
{
printf(" ##################\n");
printf(" 1.添加水果\n");
printf(" 2.删除水果-(名字)\n");
printf(" 3.排序水果-(价格)\n");
printf(" 4.修改水果-(价格)\n");
printf(" 5.打印水果\n");
printf(" 6.保存\n");
printf(" 7.加载\n");
printf(" 0.退出\n");
printf(" ##################\n");
}
修改水果价格,通过水果名
void Modify_Fruit_Price(struct fruitLink *head)
{
char name[20] = "";
double price = 0;
printf("请输入要删除水果名!\n");
scanf("%s", &name);
struct fruitLink * p = Find_Name(head, name);
if (NULL == p)
{
printf("未找到该水果名称,请检查输入的正确性!\n");
return;
}
printf("请输入新的价格!\n");
scanf("%lf", &price);
if (price <= 0)
{
printf("你他妈要赔了。。。\n");
return;
}
p->next->data.price = price;
printf("修改%s水果价格成功!\n", name);
}
按水果价格降序排列,冒泡
void Sort_Fruit_Price(struct fruitLink *head)
{
if (0 == isNullHeadNode(head)) return;
head = head->next;
struct fruitLink* t = head;
int lengh = 0;
while (head != NULL)
{
lengh++;
head = head->next;
}
for (int i = 0; i < lengh; i++)
{
head = t;
for (int j = 0; j < lengh - i - 1; j++)
{
if (head->data.price > head->next->data.price)
{
struct fruit temp = head->data;
head->data = head->next->data;
head->next->data = temp;
}
head = head->next;
}
}
printf("排序成功\n");
}
删除水果
void Del_Fruit(struct fruitLink *head)
{
char name[20] = "";
printf("请输入要删除的水果名称!\n");
scanf("%s", &name);
//验证输入水果名的正确性
if (NULL == Find_Name(head, name))
{
printf("未找到该水果名称,请检查输入的正确性!\n");
return;
}
Del_Name(head, name);
}
//通过水果名删除
void Del_Name(struct fruitLink * head, char* name)
{
if (0 == isNullHeadNode(head)) return;
//要删除节点的前一个节点
struct fruitLink* pre = Find_Name(head, name);
//要删除的节点
struct fruitLink* del = pre->next;
pre->next = del->next;
free(del);
printf("删除%s水果成功!\n", name);
}
创建一个新节点,新节点的下一个节点指向null,前节点无指向
struct fruitLink * CreateNewNode(struct fruit data)
{
//为新节点申请堆空间
struct fruitLink * newNode = calloc(1, sizeof(struct fruitLink));
newNode->data = data;
newNode->next = NULL;
return newNode;
}
判断头节点是不是为空
int isNullHeadNode(struct fruitLink *head)
{
if (NULL == head)
{
printf("头结点为空\n");
return 0;
}
return 1;
}
打印链表(循环)
void Print_Link(struct fruitLink * head)
{
struct fruitLink * head_t = head;
if (0 == isNullHeadNode(head_t)) return;
head_t = head_t->next;
printf("*************打印开始************\n");
printf("水果名\t水果价格\n");
while (head_t!=NULL)
{
printf("%s\t%lf\n", head_t->data.name, head_t->data.price);
head_t = head_t->next;
}
printf("*************打印结束************\n");
}
按水果名查找,返回前一个节点()
struct fruitLink *Find_Name(struct fruitLink * head, char * name)
{
if (0 == isNullHeadNode(head)) return NULL;
struct fruitLink * pre = head;
struct fruitLink * next = pre->next;
while (NULL != next)
{
if (0 == strcmp(next->data.name, name)) {
return pre;
}
pre = next;
next = next->next;
}
printf("没有这个水果\n");
return NULL;
}
添加水果
void Add_Fruit(struct fruitLink * head)
{
struct fruit newFruit;
printf("请输入新的水果名称\n");
scanf("%s", &newFruit.name);
if (NULL == Find_Name(head, newFruit.name))
{
printf("请输入水果价格\n");
scanf("%lf", &newFruit.price);
if (newFruit.price <= 0) {
printf("价格是负的了要赔了,你个傻逼!\n");
return;
}
Insert_After(head, newFruit);
printf("成功添加新水果\n");
return;
}
printf("应经有相同名字的水果了。。。\n");
return;
}
//向最后一个节点后插入新节点,并赋值数据
void Insert_After(struct fruitLink *head, struct fruit data)
{
struct fruitLink * head_t = head;
if (0 == isNullHeadNode(head_t))
return;
//找到最后一个节点
while (head_t->next != NULL)
{
head_t = head_t->next;
}
//最后一个节点指向新节点
head_t->next = CreateNewNode(data);
}
释放链表
void FreeAll(struct fruitLink* head)
{
if(0==isNullHeadNode(head) ) return;
struct fruitLink* temp ;
head=head->next;
while(head!=NULL)
{
temp=head->next;
free(head);
head=temp;
}
printf("链表已销毁\n");
}
保存
void Save(struct fruitLink* head)
{
if(0==isNullHeadNode(head)) return;
FILE * fp=NULL;
fp=fopen("fruit.txt","w+");
head=head->next;
while(head!=NULL)
{
//以二进制存储,会乱码
//fwrite(&head->data,sizeof(struct fruit),1,fp);
//按格式输入到流
fprintf(fp,"%s\t%lf\r\n" ,head->data.name,head->data.price);
head=head->next;
}
printf("保存成功!\n");
fclose(fp);
}
加载数据
void Load(struct fruitLink* head)
{
int flag=0;
if(0==isNullHeadNode(head)) return;
FILE * fp=NULL;
fp=fopen("fruit.txt","r+");
if(NULL==fp)
{
printf("无数据\n");
system("touch fruit.txt");
return;
}
//方法一:
while(!feof(fp))
{
struct fruit stu;
fscanf(fp,"%s\t%lf\r\n",&stu.name,&stu.price);
Insert_After(head,stu);
}
//方法二:
//while(1)
//{
// struct fruit stu;
// flag=fread(&stu,sizeof(struct fruit),1,fp);
// if(flag<1) break;
// Insert_After(head,stu);
//}
printf("加载成功\n");
fclose(fp);
}
呵呵,我也是个菜鸟,有错误还请留言,以便更正。
有更好的方法还请留言探讨,程序员快乐!!!