常用C语言多维链表函数

存一些自己写的数据结构多维链表函数,看看有没有有缘人用得上

#include "stdio.h"
#include "stdlib.h"
#include "string.h"
#define dimension 3                   /*链表数据域维度*/
#define data_type double              /*数据域数据格式*/
#define filename "./singledata.txt"   /*数据文件名*/
#define filename_w "./outputdata.txt" /*数据文件名*/
/*链表结构体*/
typedef struct Node // typedef方法函数可以对于struct Node进行重命名
{
    data_type data[dimension];
    struct Node *next;
} LNode, *LinkList; // 定义一个结构体指针方便后续的操作
LinkList InitList();
LinkList CreatListstring(int len);
LinkList read_single_data(void);
void HeadInsertList(LinkList L, int *data);
void EndInsertList(LinkList L, int *data);
void PrinfList(LinkList HeadNode);
void List_wave_filtering(LinkList HeadNode);
void List_add_elements(LinkList HeadNode, LinkList add, int subscript);
void List_delete_elements_subscript(LinkList HeadNode, int subscript);
void List_find(LinkList HeadNode, int subscript);
void List_change(LinkList HeadNode, int subscript, double *data);
void List_up_sampling(LinkList HeadNode);
void List_write_file(LinkList HeadNode);
void main()
{
    int i = 0;
    data_type data[dimension] = {0};
    LinkList A = {0}, B = {0}, C = {0};
    /*创建定长空链表*/
    A = CreatListstring(10);
    PrinfList(A);
    printf("head_len=%.4f\r\n", A->data[0]);

    /*创建定长有值链表*/
    B = CreatListstring(3);
    B->next->data[0] = 1;
    B->next->data[1] = 2;
    B->next->data[2] = 3;

    B->next->next->data[0] = 4;
    B->next->next->data[1] = 5;
    B->next->next->data[2] = 6;

    B->next->next->next->data[0] = 7;
    B->next->next->next->data[1] = 8;
    B->next->next->next->data[2] = 9;
    /*按下标增*/
    List_add_elements(A, B, 15);
    printf("增加后的链表:\r\n");
    PrinfList(A);

    /*按下标删*/
    List_delete_elements_subscript(A, 16);
    printf("删除后的链表:\r\n");
    PrinfList(A);

    /*按下标查*/
    List_find(A, 20);
    List_find(A, 16);
    /*按下标改*/
    data[0] = 1;
    data[1] = 2;
    data[2] = 3;
    List_change(A, 16, data);
    PrinfList(A);
    /*从文件读数据*/
    A = read_single_data();
    printf("原数据:\r\n");
    PrinfList(A);

    /*链表滤波*/
    List_wave_filtering(A);
    printf("滤波后:\r\n");
    PrinfList(A);

    /*链表上采样*/
    A = read_single_data();
    printf("原数据:\r\n");
    PrinfList(A);
    List_write_file(A);
    List_up_sampling(A);
    printf("上采样后:\r\n");
    PrinfList(A);

    system("pause");
}
/*-------------------------------------环境函数区-------------------------------------*/
/*创建链表*/
LinkList InitList()
{
    int i = 0;
    LinkList L = (LNode *)malloc(sizeof(LNode)); // 为头结点动态分配内存
    L->next = NULL;                              // 初始化时头结点指向空
    while (i < dimension)
    {
        L->data[i] = 0.0;
        i++;
    }
    return L;
}
void PrinfList(LinkList HeadNode) // 打印链表
{
    int i = 1;
    LinkList pMove = HeadNode->next;
    while (pMove)
    {
        printf("NO.%d[%.4f][%.4f][%.4f]\r\n", i, pMove->data[0], pMove->data[1], pMove->data[2]);
        pMove = pMove->next;
        i++;
    }
}
/*创建任意长度链表串*/
LinkList CreatListstring(int len)
{
    int i = 0;
    LinkList head = {0}, tail = {0};
    for (i = 0; len != 0 && i <= len; i++)
    {
        LinkList x = InitList();

        if (head == NULL)
        {
            head = x;
            tail = x;
        }
        else
        {
            tail->next = x;
            tail = x;
        }
    }
    head->data[0] = len;
    return head;
}
/*-------------------------------------实验函数区-------------------------------------*/
/*读取txt文件中的数据并以double型存储在链表数据域中
 所需头文件:stdio.h
            string.h
*/
LinkList read_single_data(void)
{
    int j = 0, flag = 0;
    char buffer[16] = {0}, *string;
    LinkList head = {0}, tail = {0}, y = {0};
    FILE *fp = fopen(filename, "r");
    if (fp == NULL)
        printf("singledata.txt文件不存在\r\n");
    else
    {
        while (fgets(buffer, 16, fp) != NULL)
        {
            string = strstr(buffer, "end");
            if (string != NULL)
                return head;
            j = 0;
            LinkList x = InitList();
            x->data[0] = strtod(buffer, NULL);
            for (j = 1; j < dimension; j++)
            {
                string = strstr(buffer, ",");
                if (string != NULL)
                {
                    string[0] = '0';
                    x->data[j] = strtod(string, NULL);
                }
                else
                    break;
            }
            if (head == NULL)
            {
                head = x;
                tail = x;
            }
            else
            {
                tail->next = x;
                tail = x;
            }
        }
    }
    fclose(fp);
}
void List_find(LinkList HeadNode, int subscript)
{
    int i = 0;
    double x, y, z;
    LinkList p = HeadNode->next;
    if (subscript > (int)HeadNode->data[0])
        printf("查找失败:坐标:%d。无此元素\r\n", subscript);
    else
    {
        i = 1;
        while (i < subscript)
        {
            p = p->next;
            i++;
        }
        printf("查找结果:坐标:%d,", i);
        i = 0;
        while (i < dimension)
        {
            printf("[%.4f]", p->data[i]);
            i++;
        }
        printf("\r\n");
    }
}
void List_change(LinkList HeadNode, int subscript, data_type *data)
{
    int i = 0;
    LinkList p = HeadNode->next;
    if (subscript > (int)HeadNode->data[0])
        printf("失败:无此元素\r\n");
    else
    {
        i = 1;
        while (i < subscript)
        {
            p = p->next;
            i++;
        }
        printf("修改结果:坐标:%d,", i);
        i = 0;
        while (i < dimension)
        {
            p->data[i] = data[i];
            printf("[%.4f]", p->data[i]);
            i++;
        }
        printf("\r\n");
    }
}
void List_wave_filtering(LinkList HeadNode) // 链表滤波
{
    int i = 0;
    LinkList pMove = HeadNode->next;
    while (pMove->next->next)
    {
        for (i = 0; i < dimension; i++)
            pMove->next->data[i] = (pMove->data[i] + pMove->next->data[i] + pMove->next->next->data[i]) / 3;
        pMove = pMove->next;
    }
}
void List_up_sampling(LinkList HeadNode) // 链表上采样
{
    int i = 0;
    LinkList pMove = HeadNode->next, p = {0};
    p = pMove;
    while (pMove->next)
    {
        p = InitList();
        i = 0;
        while (i < dimension)
        {
            p->data[i] = (pMove->data[i] + pMove->next->data[i]) / 2;
            i++;
        }
        p->next = pMove->next;
        pMove->next = p;
        pMove = pMove->next->next;
    }
}
void List_add_elements(LinkList HeadNode, LinkList add, int subscript) // 增加元素,输入参数:原链表、插入元素、插入下标(头结点为0)
{
    int i = 0;
    LinkList str = HeadNode->next, str2 = add->next;
    if (subscript > HeadNode->data[0]) // 下标大于原链表长度
    {
        while (str->next)
            str = str->next;
        for (i = HeadNode->data[0]; i < subscript - 1; i++)
        {
            LinkList x = InitList();
            str->next = x;
            str = x;
        }
        str->next = add->next;
        str = add->next;
        HeadNode->data[0] = subscript + add->data[0];
    }
    else
    {
        while (str2->next)
            str2 = str2->next;

        for (i = 1; i < subscript - 1; i++)
            str = str->next;
        str2->next = str->next;
        str->next = add;
        HeadNode->data[0] = subscript + add->data[0];
    }
}
void List_delete_elements_subscript(LinkList HeadNode, int subscript) // 按下标删除元素,头结点为0;
{
    LinkList p = HeadNode->next, x = {0};
    if (subscript > HeadNode->data[0])
        printf("失败:无此元素\r\n");
    else if (subscript == 0)
        printf("失败:头结点不可删除");
    else
    {
        for (int i = 1; i < subscript - 1; i++)
            p = p->next;
        x = p->next;
        p->next = p->next->next;
        free(x);
    }
}
void List_write_file(LinkList HeadNode) // 将链表打印至文本文件
{
    int i = 0;
    LinkList pMove = HeadNode->next;
    FILE *fp = fopen(filename_w, "a+");
    while (pMove->next)
    {
        i = 0;
        while (i < dimension - 1)
        {
            fprintf(fp, "%.4f,", pMove->data[i]);
            i++;
        }
        fprintf(fp, "%.4f\r\n", pMove->data[i]);
        pMove = pMove->next;
    }
    fclose(fp);
}

PS:链表滤波规则:除首节点外,其余各节点第i维的值=(前节点第i维值+本节点第i维值+后节点第i维值)/3。

上采样规则:如图所示:

LinkList read_single_data(void);文件数据格式:

data://第一行无所谓,程序会跳过该行
121,30,42
25,11,21
14,56,45
11.45,56.4,2.3
1.0,0.2,2.65
1,25,45
20,23,3.24
end//结尾行必须包含"end"

void List_write_file(LinkList HeadNode);函数输出数据格式:
data
121.0000,30.0000,42.0000
25.0000,11.0000,21.0000
14.0000,56.0000,45.0000
11.4500,56.4000,2.3000
1.0000,0.2000,2.6500
1.0000,25.0000,45.0000
end
data
121.0000,30.0000,42.0000
25.0000,11.0000,21.0000
14.0000,56.0000,45.0000
11.4500,56.4000,2.3000
1.0000,0.2000,2.6500
1.0000,25.0000,45.0000
end
每次调用该函数都会在文件尾部进行内容追加。
 

  • 2
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

睿智の男孩

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值