1.(新手小白,总体代码写的比较繁琐,见谅,勿喷)
总体代码
#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
#include <assert.h>
#include <string.h>
#include <stdlib.h>
//#include<vld.h> 用于检查内存泄漏
typedef struct listnode
{
float data; //存放系数
int cep; //存放指数
struct listnode* next;
}listnode,*linknode;
linknode creatlist(); //创建空链表
linknode buynode(); //购买节点
void printflist( linknode s); //打印一元多项式
void insert_value(linknode s); //插入数据
void push_back(linknode s); //尾插法
void push_front(linknode s); //头插法
void Freenode(linknode p); //释放内存
void clearlist(linknode s); //清空链表
void Destorylist(linknode s); //摧毁链表
int capity(linknode s); //计算项数
void rever_list(linknode s); //顺序存放
void sort(int* b, int n); //排序
int findpos(int* a, int n, int b); //查找下标
void download(linknode s, int n, int* a, float* b, int* c); //提取系数和项数
void Add(linknode a, linknode b); //多项式合并
void brief_add(linknode a); //化简合并后的多项式
void clear_brieflist(linknode s); //删除合并后的多项式的无用项
int clear_brieflist2(linknode s);
linknode buynode()
{
listnode* s = (linknode)malloc(sizeof(listnode));
if (NULL == s) exit(1);
memset(s, 0, sizeof(listnode));
return s;
}
linknode creatlist()
{
return buynode();
}
void printflist( linknode s)
{
assert(s != NULL);
linknode p = s->next;
while (NULL != p)
{
if (p->data == 0) {
p = p->next;
continue;
}
printf("%.2lf(X)^%d", p->data, p->cep);
if (p->next != NULL ) printf("+");
p = p->next;
}
printf("\n");
}
void Freenode(linknode p)
{
free(p);
p = NULL;
}
void insert_value(linknode s)
{
linknode cp = buynode();
scanf("%f,%d",& cp->data,& cp->cep);
cp->next =s->next;
s->next = cp;
}
void push_back(linknode s)
{
assert(NULL != s);
while (NULL != s->next)
s = s->next;
insert_value(s);
}
void push_front(linknode s)
{
assert(NULL != s);
insert_value(s);
}
void clearlist(linknode s)
{
assert(s != NULL);
while (NULL != s->next)
{
linknode p;
p = s->next;
s->next = p->next;
Freenode(p);
}
}
void Destorylist(linknode s)
{
clearlist(s);
Freenode(s);
}
int capity(linknode s)
{
assert(NULL != s);
int n = 0;
while (s->next != NULL)
{
n++;
s = s->next;
}
return n;
}
void rever_list(linknode s)
{
assert(NULL != s);
int n = capity(s);
int* a = (int*)malloc(sizeof(int) * n); //顺序存放
float* b = (float*)malloc(sizeof(float) * n); //链表顺序
int* c = (int*)malloc(sizeof(int) * n); //链表顺序
download(s, n,a,b,c);
s = s->next;
for(int i=0,j=0;i<n;i++)
{
j = findpos(c, n, a[i]); //
s->data = b[j];
s->cep = a[i];
s =s->next;
}
free(a);
free(b);
free(c);
a = NULL;
b = NULL;
c = NULL;
}
void sort(int* b, int n)
{
assert(NULL != b);
int temp;
for (int i = 0; i < n-1; i++)
for (int j = 0; j < n -1- i; j++)
if (b[j] < b[j+1])
{
temp = b[j];
b[j] = b[j+1];
b[j+1] = temp;
}
}
int findpos(int*a,int n, int b)
{
assert(NULL != a);
int i;
for (i = 0; i < n ; i++)
{
if (a[i] == b)
{
a[i] = 0;
return i;
}
}
}
void download(linknode s, int n,int* a,float* b,int* c)
{
assert(NULL != s);
linknode p = s->next;
for (int i = 0; i < n; i++)
{
a[i] = p->cep;
c[i] = p->cep;
b[i] = p->data;
p = p->next;
}
sort(a, n);
}
void Add(linknode a, linknode b)
{
int n=0;
assert(NULL != a && NULL != b);
n = capity(a) + capity(b);
while (a->next != NULL)
a=a->next;
a->next = b->next;
b->next = NULL;
Freenode(b);
}
void brief_add(linknode a)
{
int n = capity(a),i=0,j;
linknode p = a->next;
linknode q = a;
float* b = (float*)malloc(sizeof(float) * n);
int* c = (int*)malloc(sizeof(int) * n);
while (a->next != NULL)
{
b[i] = a->next->data;
c[i] = a->next->cep;
a = a->next;
i++;
}
for (i = 0 ; i < n; i++)
for (j = i + 1; j < n; j++)
{
if (c[i] == c[j]) {
b[i] += b[j];
b[j] = 0;
}
}
for (i = 0; i < n; i++)
{
p->data = b[i];
p= p->next;
}
clear_brieflist(q);
free(b);
free(c);
}
void clear_brieflist(linknode s)
{
assert(s != NULL);
int i = 0;
linknode p = s;
while (NULL!=s->next)
{
s = s->next;
}
if (s->data == 0) {
while (i <= clear_brieflist2(p))
p = p -> next;
}
clearlist(p);
}
int clear_brieflist2(linknode s)
{
assert(s != NULL);
int i = 0,n=capity(s);
float* a = (float*)malloc(sizeof(float) *n );
while (NULL != s->next)
{
a[i] = s->next->data;
s = s->next;
i++;
}
for (i = n-1;; i--)
{
if (a[i] != 0) {
free(a);
return i;
}
}
}
int main()
{
int n=0,m=0;
listnode* a = creatlist();
printf("请输入多项式a个数:");
scanf("%d", &n);
for (int i = 0; i < n; i++)
{
printf("请输入多项式a第%d项的系数和指数:", i + 1);
push_front(a);
}
printf("原一元多项式a为:");
printflist(a);
printf("排序后的一元多项式a为:");
rever_list(a);
printflist(a);
listnode* b = creatlist();
printf("请输入多项式b个数:");
scanf("%d", &m);
for (int i = 0; i < m; i++)
{
printf("请输入多项式b第%d项的系数和指数:", i + 1);
push_back(b);
}
printf("原一元多项式b为:");
printflist(b);
printf("排序后的一元多项式b为:");
rever_list(b);
printflist(b);
Add(a, b);
printf("合并后的一元多项式b为:");
printflist(a);
rever_list(a);
brief_add(a);
printf("合并排序化简后的一元多项式b为:");
printflist(a);
Destorylist(a);
return 0;
}
注(main函数可自行设定)
1.结构体定义
typedef struct listnode
{
float data; //存放系数
int cep; //存放指数
struct listnode* next;
}listnode,*linknode;
注解:*linknode为指针,是指向lisinode类型的指针。
2.建立链表
linknode buynode()
{
listnode* s = (linknode)malloc(sizeof(listnode));
if (NULL == s) exit(1);
memset(s, 0, sizeof(listnode));
return s;
}
linknode creatlist()
{
return buynode();
}
定义linknode 型函数,内部动态申请内存。
3.输出链表
void printflist( linknode s)
{
assert(s != NULL);
linknode p = s->next;
while (NULL != p)
{
if (p->data == 0) {
p = p->next;
continue; //防止无效项输出(系数为0)
}
printf("%.2lf(X)^%d", p->data, p->cep);
if (p->next != NULL ) printf("+");
p = p->next;
}
printf("\n");
}
4.插入函数(向链表里放入数据)
void insert_value(linknode s)
{
linknode cp = buynode();
scanf("%f,%d",& cp->data,& cp->cep);
cp->next =s->next;
s->next = cp;
}
原理图如下:先构建一个节点,进行插入(先断右链,再断左链,不然会造成数据丢失,无法找到下一节点地址。
1.头插法
void push_front(linknode s)
{
assert(NULL != s);
insert_value(s);
}
2.尾插法
void push_back(linknode s)
{
assert(NULL != s);
while (NULL != s->next)
s = s->next;
insert_value(s);
}
5.清空链表
1.释放节点
void Freenode(linknode p)
{
free(p);
p = NULL;
}
2.无限头删法
void clearlist(linknode s)
{
assert(s != NULL);
while (NULL != s->next)
{
linknode p;
p = s->next;
s->next = p->next;
Freenode(p);
}
}
3.摧毁头节点
void Destorylist(linknode s)
{
clearlist(s);
Freenode(s);
}
6.计算数据个数(链表容量)
int capity(linknode s)
{
assert(NULL != s);
int n = 0;
while (s->next != NULL)
{
n++;
s = s->next;
}
return n;
}
7.排序(更改链表数据域,使指数从高到底)
1.保存原链表的数据(用数组保存)
void download(linknode s, int n,int* a,float* b,int* c)
{
assert(NULL != s);
linknode p = s->next;
for (int i = 0; i < n; i++)
{
a[i] = p->cep;
c[i] = p->cep;
b[i] = p->data;
p = p->next;
}
sort(a, n);
}
2.排序(将指数进行排序)
void sort(int* b, int n)
{
assert(NULL != b);
int temp;
for (int i = 0; i < n-1; i++)
for (int j = 0; j < n -1- i; j++)
if (b[j] < b[j+1])
{
temp = b[j];
b[j] = b[j+1];
b[j+1] = temp;
}
}
3.查找下标
int findpos(int*a,int n, int b)
{
assert(NULL != a);
int i;
for (i = 0; i < n ; i++)
{
if (a[i] == b)
{
a[i] = 0;
return i;
}
}
}
4. 重新给链表赋值,使其有序
void rever_list(linknode s)
{
assert(NULL != s);
int n = capity(s);
int* a = (int*)malloc(sizeof(int) * n); //顺序存放
float* b = (float*)malloc(sizeof(float) * n); //链表顺序
int* c = (int*)malloc(sizeof(int) * n); //链表顺序
download(s, n,a,b,c);
s = s->next;
for(int i=0,j=0;i<n;i++)
{
j = findpos(c, n, a[i]); //返回原链表指数的下标
s->data = b[j];
s->cep = a[i];
s =s->next;
}
free(a);
free(b);
free(c);
a = NULL;
b = NULL;
c = NULL;
}
8.合并两个链表
合并方式如图
void Add(linknode a, linknode b)
{
int n=0;
assert(NULL != a && NULL != b);
n = capity(a) + capity(b);
while (a->next != NULL)
a=a->next;
a->next = b->next;
b->next = NULL;
Freenode(b);
}
9.化简合并后的链表
1.找到同类项(指数相同),将系数求和赋给第一个同类项,后续系数赋为0.
void brief_add(linknode a)
{
int n = capity(a),i=0,j;
linknode p = a->next;
linknode q = a;
float* b = (float*)malloc(sizeof(float) * n);
int* c = (int*)malloc(sizeof(int) * n);
while (a->next != NULL)
{
b[i] = a->next->data;
c[i] = a->next->cep;
a = a->next;
i++;
}
for (i = 0 ; i < n; i++)
for (j = i + 1; j < n; j++)
{
if (c[i] == c[j]) {
b[i] += b[j];
b[j] = 0;
}
}
for (i = 0; i < n; i++)
{
p->data = b[i];
p= p->next;
}
clear_brieflist(q);
free(b);
free(c);
}
2.判断尾结点数据域中系数是否0,并清除链表中无效节点(某一节点到尾结点的数据域中系数全为0)
void clear_brieflist(linknode s)
{
assert(s != NULL);
int i = 0;
linknode p = s;
while (NULL!=s->next)
{
s = s->next;
}
if (s->data == 0) {
while (i <= clear_brieflist2(p))
p = p -> next;
}
clearlist(p);
}
3.找到链表中最后一个数据域中系数不为0的结点为几号。
int clear_brieflist2(linknode s)
{
assert(s != NULL);
int i = 0,n=capity(s);
float* a = (float*)malloc(sizeof(float) *n );
while (NULL != s->next)
{
a[i] = s->next->data;
s = s->next;
i++;
}
for (i = n-1;; i--)
{
if (a[i] != 0) {
free(a);
a=NULL;
return i;
}
}
}
最后运行一下代码
可以看到代码正常运行,且无内存泄漏。