C语言单链表

来源:互联网 发布:win7网络诊断dns未响应 编辑:程序博客网 时间:2024/05/22 11:55

不多说,直接上马,一个水果实例:

#include <stdio.h>#include <stdlib.h>#include <string.h>//这是跳过警告,在vs编译器中使用,需加上词句#pragma warning(disable:4996)#define WHILE_ONE 1struct 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-1int 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保存到txtvoid 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);}

呵呵,我也是个菜鸟,有错误还请留言,以便更正。
有更好的方法还请留言探讨,程序员快乐!!!