单链表的基本操作

 

前言

本程序用实现了链表的头插尾插,对文件读取的应用,基本的插删工作,并对部分操作注释了自己的理解,程序并不复杂,单由于个人水平有限可能还有不足,欢迎各位大佬指正 作者学号(2019060745)


1.引入库函数

代码如下(示例):

#include <stdio.h>
#include <stdlib.h>
#include <malloc.h>

2.读入数据

link *qqqqqqqqqq() { //!从文件中导出到链表
    FILE *fp;
    fp = fopen("D:\\lianbiao12.txt", "r");
    link *head, *next, *end;
    head = (link *)malloc(sizeof(link));
    head->LNond = NULL;
    end = head;

    while (!feof(fp)) { //feof函数有俩个返回值,非文件尾返回0,文件尾返回非0
        next = (link *)malloc(sizeof(link));
        fscanf(fp,"%d", &next->date); //1 表示从fp指向的文件中读取一个量存入变量
        end->LNond = next;
        end = next;
    }

    end->LNond = NULL;
    fclose(fp);
    return (head); 

}

总结

  1. #include <stdio.h>
    
    #include <stdlib.h>
    
    #include <malloc.h>
    
    typedef struct link {
    
        int date;
    
        struct link* LNond;
    
    } link;
    
    
    
    link *InsScanf_after();//!输入 尾插
    
    link *InsScanf_first();//头插
    
    void InsFile_txt(link *head); //!保存数据到文件
    
    link *qqqqqqqqqq(); //!从文件中导出到链表
    
    void InsBefore(link *head);//!插入元素
    
    void InsPrintf(link *head);  //!输出到控制台
    
    void InsDelete(link *head);//!删除元素
    
    void InsLength(link *head); //!表长
    
    void Getelem_L(link *head); //!查找元素
    
    void minu(); 
    
    void minu() {
    
        {
    
            link *HeadReturn = NULL;
    
            int number;
    
            printf("您选择了“链表”\n");
    
            printf("##############################\n");
    
            printf("#   1----前插建立链表        #\n");
    
            printf("#   2----后插建立链表        #\n");
    
            printf("#   3----插入                #\n");
    
            printf("#   4----输出到控制台        #\n");
    
            printf("#   5----删除                #\n");
    
            printf("#   6----求线性表的表长      #\n");
    
            printf("#   7----访问第i个元素       #\n");
    
            printf("#   8----从文件中导出到链表  #\n");
    
            printf("#   9----写入文件           #\n");
    
            printf("#   0----退出                #\n");
    
            printf("##############################\n");
    
            printf("请输入选择:(0-6):");
    
            scanf("%d", &number);
    
            while (number != 0) {
    
                switch (number) {
    
                    case 1:
    
                        HeadReturn = InsScanf_after();
    
                        break;
    
                    case 2:
    
                        HeadReturn =InsScanf_first(); 
    
                        break; //!头插 
    
                    case 3:
    
                        InsBefore(HeadReturn);
    
                        break; //!插入
    
                    case 8:
    
                        HeadReturn=qqqqqqqqqq();
    
                        break; //!从文件中导出到链表
    
                    case 4:
    
                        InsPrintf(HeadReturn);
    
                        break; //!输出到控制台
    
                    case 5:
    
                        InsDelete(HeadReturn);
    
                        break; //!删除
    
                    case 6:
    
                        InsLength(HeadReturn);
    
                        break; //!表长
    
                    case 7:
    
                        Getelem_L(HeadReturn);
    
                        break; //!查找
    
                    case 9:
    
                        InsFile_txt(HeadReturn);
    
                        break; //!有待开发的文件 
    
                }
    
                printf("输入下一步操作\n");
    
                scanf("%d", &number);
    
            }
    
        }
    
    }
    
    
    
    link *InsScanf_after() { //!输入 尾插
    
        int i = 0;
    
        link *head, *next, *end;
    
        head = (link*)malloc(sizeof(link));
    
        if (head) printf("已分配空间,请输入链表长度\n");
    
        scanf("%d", &head->date);
    
        head->LNond = NULL;
    
        end = head;
    
        while (i < head->date) {
    
            next = (link*)malloc(sizeof(link));
    
            scanf("%d", &next->date);
    
            next->LNond = NULL;
    
            end->LNond = next;//新结点放入end指针域或者说end指向新结点 
    
            end = next;//把next作为新的尾结点end 
    
            i++;
    
        }
    
        next->LNond = NULL;
    
        end = next;
    
        return head;
    
    }
    
    
    
    link *InsScanf_first() { //头插:插到头结点和首元节点(第一个结点)之间 
    
        int i = 0;
    
            link *head,*s_new;
    
            head = (link*)malloc(sizeof(link));
    
            if (head) printf("已分配空间,请输入链表长度\n");
    
            scanf("%d", &head->date);
    
            s_new = (link*)malloc(sizeof(link));//生成首元结点 
    
            scanf("%d", &s_new->date);
    
            head->LNond =s_new;
    
            s_new->LNond=NULL; 
    
            while(i < head->date-1)
    
            {
    
                s_new = (link*)malloc(sizeof(link));
    
                scanf("%d", &s_new->date);
    
                s_new->LNond = head->LNond; //将新结点插入到头结点和首元节点之间 
    
                head->LNond = s_new;//新结点放入head指针域或者说head指向新结点
    
                i++;
    
            }
    
             
    
            return head;
    
    }
    
    
    
    void InsFile_txt(link *head) { //!保存数据到文件
    
        link *next;
    
        next = head->LNond;
    
        FILE *fp;
    
        fp = fopen("D:\\lianbiao12.txt", "a+");
    
        while (next != NULL) {
    
            fprintf(fp, " %d", next->date);
    
            next = next->LNond;
    
        }
    
        getchar();
    
        fclose(fp);
    
        printf("输出成功");
    
    }
    
    
    
    link *qqqqqqqqqq() { //!从文件中导出到链表
    
            //int i = 0;
    
        //int a;
    
        FILE *fp;
    
        fp = fopen("D:\\lianbiao12.txt", "r");
    
        //int *p1;
    
        link *head, *next, *end;
    
        head = (link *)malloc(sizeof(link));
    
        head->LNond = NULL;
    
        end = head;
    
    
    
        while (!feof(fp)) { //feof函数有俩个返回值,非文件尾返回0,文件尾返回非0
    
            next = (link *)malloc(sizeof(link));
    
            fscanf(fp,"%d", &next->date); //1 表示从fp指向的文件中读取一个量存入变量
    
            end->LNond = next;
    
            end = next;
    
    
    
        }
    
        end->LNond = NULL;
    
        fclose(fp);
    
        return (head); 
    
    }
    
    
    
    void InsBefore(link *head) { //!插入元素
    
        int i = 0, a = 0, Check = 1; //循环次数 位置  位置校验
    
        link *next, *p;
    
        next = head;//此处用head而不用head->LNond的原因为:head内存放的是第一个结点next的地址,如果用head->LNond则会丢失头结点地址(
    
        //头结点内储存的数据还在,也可正常输出),导致插入的元素位置实际为想要插入位置后一位
    
        while (Check) {
    
            printf("请输入要插入元素位置(输0退出)");
    
            scanf("%d", &a);
    
            if (a <= head->date + 1 && a > 0) Check = 0;
    
            else if(a==0) return;
    
            else printf("位置不合理,请重新输入\n");
    
        }
    
        while ((next->LNond) && i < a - 1) {
    
        next = next->LNond;
    
            i++;
    
        }
    
        printf("要插入的值为:");
    
        p = (link*)malloc(sizeof(link));
    
        scanf("%d", &p->date);
    
        p->LNond = next->LNond; //将 工作指针next->内存放的下一结点的地址存放到插入结点P->LNond内
    
        next->LNond = p; //用插入结点p的地址覆盖工作指针next内存放的地址
    
        head->date++;
    
    }
    
    
    
    void InsPrintf(link *head) { //!输出到控制台
    
        link *next;
    
        next = head->LNond;
    
        printf("输出");
    
        while (next) {
    
            printf("%4d", next->date);
    
            next = next->LNond;
    
        }
    
    
    
    }
    
    
    
    void InsDelete(link *head) { //!删除元素
    
        int i = 0, a = 0; //循环次数 删除位置
    
        link *next, *p1;
    
        next = head;//此处用head而不用head->LNond的原因为:head内存放的是第一个结点next的地址,如果用head->LNond则会丢失头结点地址(
    
        //头结点内储存的数据还在,也可正常输出),导致删除的元素实际为想要删除元素后一位的元素
    
        printf("请输入要删除元素位置");
    
        scanf("%d", &a);
    
        if (a > head->date) {
    
            printf("位置不存在");
    
            return;
    
        }
    
        while ((next->LNond) && i < a - 1) {
    
            printf("%4d", next->date);
    
            next = next->LNond;
    
            i++;
    
            printf("删除的%d为%d\n", i, next->date);
    
        }
    
        p1 = next->LNond;
    
        printf("删除的为%d\n", p1->date);
    
        next->LNond = p1->LNond;
    
        free(p1);
    
        head->date--;
    
    }
    
    
    
    void InsLength(link *head) { //!表长
    
        link *next;
    
        int n = 0;
    
        next = head->LNond;
    
        printf("输出");
    
        while (next) {
    
            next = next->LNond;
    
            n++;
    
        }
    
        printf("表长为%d", n);
    
        head->date = n;
    
    }
    
    
    
    void Getelem_L(link *head) { //!查找元素
    
        int i = 0, a = 0, Check = 3; //循环次数 位置  位置校验
    
        link *next;
    
        next = head->LNond;
    
        while (Check) {
    
            printf("请输入要查找元素位置(输0退出)");
    
            scanf("%d", &a);
    
            if ((int)a > head->date + 1) printf("位置不合理,请重新输入或退出(0)\n");
    
            else if( a == 0) return;
    
            else Check=0;
    
        }
    
        while ((next->LNond) && i < a - 1) {
    
            next = next->LNond;
    
            i++;
    
        }
    
        printf("第%d个元素为%4d", a, next->date);
    
    }
    
    
    
    int main() {
    
        minu(); 
    
        return 0;
    
    }

     

  • 2
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值