存一些自己写的数据结构多维链表函数,看看有没有有缘人用得上
#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
每次调用该函数都会在文件尾部进行内容追加。