• C语言提高 (6) 第六天 文件(续) 链表的操作


     

    1昨日回顾

     

    #define _CRT_SECURE_NO_WARNINGS

    #include <stdio.h>

    #include <stdlib.h>

    #include <string.h>

     

    int main(int argc, char* argv[])

    {

        char buf[1024] = { 0 };

        int len = 0;

     

        // !可以取代scanf

        if (fgets(buf, 1024, stdin) != NULL) {

            len = strlen(buf);

            buf[len - 1] = ''; // 输入以后是qwe 所以最后一个 要换成

        }

     

        printf("buf:%s ", buf);

     

        return 0;

    }

    刚才的读写都是字符和字符串,下面讲二进制的读写:

    (ue查看二进制文件)

    2作业题

    对操作系统来说都是文件 设备文件…

    是写驱动的人为我们提供了接口

    3文件系统体系

    问:这个能编译吗?

    struct 是一种数据类型

    数据类型是固定内存大小的别名

    这样可以:

    数组与链表的对比:

    4文件缓冲区

    再说一下fgets和fputs

    fgets遇到 结束,也就是读取一行,最后会把 也读进去 不会读

    fputs不会把 put出去,fputs只是put string

    5静态链表和动态链表

     

    2)

    带头链表和不带头链表

    无头链表的插入和从头部插入,删除节点..等操作

    no_head_list.h:

    #ifndef _NO_HEAD_LIST_H_

    #define _NO_HEAD_LIST_H_

     

    #define _CRT_SECURE_NO_WARNINGS

    #include <stdio.h>

    #include <string.h>

     

     

     

    // 链表的节点

    struct node

    {

        int data; //数据域

        struct node *next; //指针域

    };

     

     

    // 初始化链表的接口

    void init_list(struct node **head_p);

     

     

    // 创建一个节点的接口

    struct node* make_node(int data);

     

    // 销毁一个节点

    void free_node(struct node *node);

     

     

    // 将节点插入链表的接口 (插入链表的尾部

    int insert_node_to_end(struct node *new_node,struct node**head_p);

     

     

    // 将节点插入链表的头部

    int insert_node_from_begin(struct node *new_node, struct node **head_p);

     

    // 销毁一个链表

    void destory_list(struct node **head_p);

     

     

    // 遍历链表

    void print_list(struct node *head);

     

     

    // 删除一个节点,根据要删除节点的指针来删除

    int delete_node(struct node*del_node, struct node **head_p);

     

    // 查询一个节点

    struct node * search(struct node *head, int data);

     

     

    #endif

    no_head_list.c:

    #include "no_head_list.h"

     

    void init_list(struct node **head_p)

    {

        *head_p = NULL;

    }

     

    struct node* make_node(int data)

    {

        struct node *new_node = NULL;

     

        new_node = (struct node *)malloc(sizeof(struct node));

        if (new_node == NULL)

        {

            fprintf(stderr, "make node malooc new_node error ");

            return NULL;

        }

        memset(new_node, 0, sizeof(struct node));

           

        new_node->data = data;

        new_node->next = NULL;

     

        return new_node;

    }

     

     

    // 插入一个节点到head中

    int insert_node_to_end(struct node *new_node, struct node**head_p)

    {

        struct node *head = NULL;

        struct node* last_node = NULL;

     

        if (new_node == NULL || head_p == NULL)

        {

            return 0;

        }

     

        head = *head_p;

     

        if (head == NULL)

        {

            // 链表此时是空链表

            head = new_node;

            last_node = new_node; // 无头链表特点:需要对head是否为空 进行判断

        }

        else {

            // 找到这个last_node

            // last_node->next = new_node;

     

            for (last_node = head; last_node->next != NULL; last_node = last_node->next);

            last_node->next = new_node;

        }

     

        *head_p = head;

     

        return 0;

    }

     

     

    // 遍历链表

    void print_list(struct node *head)

    {

        struct node *p = NULL;

        for (p = head; p != NULL; p = p->next) {

            printf("%d ", p->data);

        }

    }

     

     

    int insert_node_from_begin(struct node *new_node, struct node **head_p)

    {

        if (new_node == NULL || head_p == NULL)

        {

            return -1;

        }

     

        struct node *head = *head_p;

     

     

        // 插入的操作

     

        if (head == NULL)

        {

            head = new_node;

        }

        else {

            new_node->next = head;

            head = new_node;

        }

     

        *head_p = head;

     

        return 0;

    }

     

    void free_node(struct node *node)

    {

        if (node != NULL) {

            free(node);

        }

    }

     

     

    void destory_list(struct node **head_p)

    {

        struct node *head = *head_p;

        struct node *p = NULL;

     

        while (head!= NULL)

        {

            // 链表还有怨怒是

            p = head;

            head = head->next;

            free(p);

        }

     

     

        *head_p = head;

    }

     

    int delete_node(struct node*del_node, struct node **head_p)

    {

        struct node *head = *head_p;

        struct node *p = NULL;

     

     

     

        if (head == del_node) {

            // 如果要删除的节点就是首节点

            head = head->next;

            free_node(del_node);

            *head_p = head;

       

           

            return 0;

        }

     

        // 要删除的不是头节点

        for (p = head; p != NULL; p = p->next)

        {

            if (p->next == del_node) {

                // 找到了要删除的节点,此时p是这个要删除节点的前驱节点

                p->next = p->next->next;

                free_node(del_node);

                break;

            }

        }

     

        *head_p = head;

         return 0;

    }

     

     

    // 查询一个节点

    struct node* search(struct node*head, int data)

    {

        struct node *p = NULL;

     

        for (p = head; p != NULL; p = p->next) {

            if (p->data == data)

            {

                return p;

            }

        }

     

        return NULL;

    }

     

    main.c:

    #define _CRT_SECURE_NO_WARNINGS

    #include <stdio.h>

    #include <string.h>

     

     

    int main(void)

    {

        struct node *head = NULL;

        struct node *new_node = NULL;

        int num = 10;

        int i = 0;

        int del_data = 0;

     

        // 初始化头节点

        init_list(&head);

     

        // 创建一个链表节点

        for (i = 0; i < num; i++) {

            new_node = make_node(i + 10);

            //insert_node_to_end(new_node, &head);

            insert_node_from_begin(new_node,&head);

        }

     

        print_list(head);

     

        printf("请输入要删除的节点:");

        scanf("%d", &del_data);

        struct node *del_node = search(head, del_data);

        if (del_node != NULL)

        {

            delete_node(del_node, &head);

        }

     

        printf("--------- ");

     

        print_list(head);

     

     

        // 销毁一个链表

        destory_list(&head);

     

        if (head == NULL)

        {

            printf("head === NULL");

        }

     

        return 0;

    }

    带头节点链表的操作:

    双向链表(带头):

    删除双向链表节点:

    销毁一个双向链表:

    dlist.h

    #ifndef _D_LIST_H_

    #define _D_LIST_H_

     

    #define _CRT_SECURE_NO_WARNINGS

    #include <stdio.h>

    #include <string.h>

     

     

    struct node

    {

        int data; //数据域

        struct node *next; //下一个节点

        struct node *prev; //上一个节点

    };

     

     

    // 初始化一个双向链表

    void init_list(struct node **head_p,struct node**tail_p);

     

     

    // 创建一个节点

    struct node *make_node(int data);

     

     

    // 销毁一个节点

    void free_node(struct node *node);

     

     

    // 插入一个节点

    int insert_node(struct node*head, struct node*tail, struct node*new_node);

     

    // 顺序遍历

    void print_list_1(struct node *head, struct node *tail);

     

    // 逆序遍历

    void print_list_2(struct node *head, struct node *tail);

     

    // 查找一个节点

    struct node* search(struct node* head, struct node* tail, int data);

     

     

    // 删除一个双向链表的节点

    int delete_node(struct node* head, struct node* tail, struct node* del_node);

     

     

    // 销毁一个双向链表

    void destory_list(struct node* head, struct node* tail);

     

    #endif

    dlist.c:

    #define _CRT_SECURE_NO_WARNINGS

    #include <stdio.h>

    #include <string.h>

    #include <stdlib.h>

    #include "dlist.h"

     

     

    // 初始化一个双向链表

    void init_list(struct node **head_p, struct node**tail_p)

    {

        struct node *head = NULL;

        struct node *tail = NULL;

        if (head_p == NULL || tail_p == NULL)

        {

            return;

        }

     

        head = (struct node *)malloc(sizeof(struct node));

        if (head == NULL)

        {

            return;

        }

     

        tail = (struct node*) malloc(sizeof(struct node));

       

        if (tail == NULL) {

            return;

        }

     

        head->data = tail->data = 0;

        head->next = tail;

        tail->prev = head;

     

        head->prev = tail->next = NULL;

     

        *head_p = head;

        *tail_p = tail;

     

        return;

    }

     

     

    // 创建一个节点

    struct node *make_node(int data)

    {

        struct node *p = NULL;

     

        p = (struct node*)malloc(sizeof(struct node));

        if (p == NULL)

        {

            return NULL;

        }

     

        p->data = data;

        p->next = p->prev = NULL;

     

        return p;

    }

     

     

    void free_node(struct node *node) {

        if (node == NULL) return;

        free(node);

    }

     

    int insert_node(struct node*head, struct node*tail, struct node*new_node)

    {

     

        if (head == NULL || tail == NULL || new_node == NULL)

        {

            return -1;

        }

     

        //插入哪个节点就先改变哪个节点的next和prev

        // 改变new_node的自身指针

        new_node->next = head->next;

        new_node->prev = head;

       

        // 改变new_node两边的指针

        new_node->next->prev = new_node;

        new_node->prev->next = new_node;

     

     

        return 0;

    }

     

    // 遍历一个链表

    void print_list_1(struct node *head, struct node *tail)

    {

       

        struct node *p = NULL;

     

        for (p = head->next; p != tail; p = p->next)

        {

            printf("data:%d ", p->data);

        }

     

    }

     

    void print_list_2(struct node *head, struct node *tail)

    {

        struct node *p = NULL;

     

        for (p = tail->prev; p != head; p = p->prev)

        {

            printf("data:%d ", p->data);

        }

    }

     

     

    // 查找一个节点

    struct node* search(struct node* head, struct node* tail,int data)

    {

        struct node* p = NULL;

     

        for (p = head->next; p != tail; p = p->next)

        {

            if (p->data == data)

            {

                return p;

            }

        }

     

        return NULL;

    }

     

    // 删除一个双向链表节点

    int delete_node(struct node* head, struct node* tail, struct node* del_node)

    {

        struct node* p = NULL;

     

        for (p = head->next; p != tail; p = p->next) {

            //遍历链表中除了head和tail的每一个元素

            if (p == del_node) {

                // p是删除的节点

                // 应该改变p的前驱节点和p的后继节点,p本身的两个指针不要动

                p->next->prev = p->prev;

                p->prev->next = p->next;

                free_node(p);

                break;

            }

        }

        return 0;

    }

     

    // 销毁一个双向链表

    void destory_list(struct node** head_p, struct node** tail_p)

    {

     

        if (head_p == NULL || tail_p == NULL)

        {

            return;

        }

     

        struct node* head = *head_p;

        struct node* tail = *tail_p;

        struct node* p = NULL;

     

        for (p = head->next; p != tail;)

        {

            p->next->prev = p->prev;

            p->prev->next = p->next;

            free_node(p);

            p = head->next;

        }

     

        // 以上就删除了 除了head和tail的全部元素

     

        if (head->next = tail && tail->prev == head)

        {

            printf("此时链表已经空 除了head ail ");

            free_node(head);

            free_node(tail);

            *head_p = NULL;

            *tail_p = NULL;

        }

     

        return;

    }

    main.c:

    #define _CRT_SECURE_NO_WARNINGS

    #include <stdio.h>

    #include <string.h>

    #include "dlist.h"

     

    int main(void)

    {

        struct node *head = NULL;//表头

        struct node *tail = NULL;//表尾

        struct node *new_node = NULL;

        struct node* del_node = NULL;

     

        int num = 10;

        int i = 0;

        int data = 0;

     

        init_list(&head, &tail);

     

        for (i = 0; i < num; i++)

        {

            new_node = make_node(i + 10);

            insert_node(head, tail, new_node);

        }

     

        print_list_1(head, tail);

     

        printf("========== ");

     

        print_list_2(head, tail);

     

     

        printf("data:");

        scanf("%d", &data);

     

        del_node = search(head,tail,data);

        if (del_node != NULL)

        {

            delete_node(head, tail, del_node);

        }

     

     

        printf("========== ");

     

     

        print_list_2(head, tail);

     

     

        destory_list(&head, &tail);

     

        if (head == NULL)

        {

            printf("head == NULL ");

        }

     

        if (tail == NULL)

        {

            printf("tail == NULL ");

        }

     

        return 0;

    }

    总结:

    对于插入删除链表效率比较高

    对于索引链表效率比较低,(数组可以直接偏移

    关于有头无头:

    有了头结点之后,对首个结点的操作(比如删除、插入等)可以和其他节点相同,

    “大家都说的差不多了,有头的好,没头的怎么找入口。”

    回调函数

    void(*)() 是个 返回值为 void; 参数为空 (这样些也成 void(*)(void) )的函数指针
    注意 是个 函数指针
    然后 把0 强制转换为 这个类型的指针
    然后 取 值 *(void(*)())
    这个时候 就是 取得了 一个函数指针 类型为 返回值为 void; 参数为空
    然后 后面加上 括号 就是 实施这个 函数指针的调用

  • 相关阅读:
    Thrift全面介绍
    ZooKeeper全面介绍
    Redis全面介绍
    第三篇:彻底解决ssh.invoke_shell() 返回的中文问题
    第二篇:ssh.invoke_shell() 切换root出现的新问题
    第一篇:UnicodeDecodeError: 'utf-8' codec can't decode byte 0xc3 in position 0: invalid continuation byte
    pycharm安装 suds模块报错:AttributeError: module 'pip' has no attribute 'main'
    变量赋值理解--Pyton中让两个值互换的方法
    02 Django框架基础(APP的创建访问)
    01 Web框架介绍
  • 原文地址:https://www.cnblogs.com/eret9616/p/10368775.html
Copyright © 2020-2023  润新知