一个一元多项式相加,蕴涵的知识和编程心得
先定义头文件t11.h#include"stdio.h"
#include"string.h"
#include"ctype.h"
#include"malloc.h"
#include"stdlib.h" //atoi(),exit();
#include"io.h" //eof()
#include"math.h"
#define TRUE 1
#define FALSE 0
#define OK 1
#define ERROR 0
typedef int Status;
typedef int Boolean;
再定义数据结构类型,也包含在头文件里f1.h
typedef struct Node
{
float num;
int zs;
struct Node*next;
}node,*linklist;
再就是自己的实现函数,也是最核心的东西,有点乱哈!定义在文件feilei.cpp里
void initfen(linklist &L) //初始化程序,分配一个头结点空间,但不存数据。
{
L=(linklist)malloc(sizeof(struct Node));
if(!L)
{
printf("内存分配失败!!");
exit(1);
}
}
void ListDelete(linklist &head,int e) // 删除指定数e的函数
{
linklist p1,q1,t1;
q1=head;
t1=p1 = head->next;
if(p1 == NULL) //链表中一个元素也没有。
{
printf("退出!!链表中没有元素!!!");
exit(1);
}
if(p1->next == NULL) // 第一个元素后无节点
{
if(p1->num == e) // 第一个节点是要删除的位置
{
free(t1); // 头结点指针置空
t1=NULL; // 释放p1
p1=NULL;
printf("表为空!!!!无数据!!");
exit(1);
}
else
{
printf("\n只有一个节点!\n");
}
}
while(p1 != NULL) // 循环条件
{
if(p1->num == e) // 当前指针的位置是要删除的节点
{
if(p1->next == NULL) // 当前位置是最后一个节点
{
q1->next=NULL; // 将p1当前节点的前一个节点的指正置空
free(p1); // 释放p1
p1=NULL; // 将p1置空 是为了结束条件循环
}
else // p1位置是要删除的元素 但p1的下一个元素不为空
{
q1->next=p1->next; // 将q1节点的指针指向p1的下一个指针
free(p1); // 释放 p1
p1=q1->next; // 重新将p1指向q1节点的前一个
}
}
else // p1 当前位置不是要删除的位置
{
q1=q1->next;
p1=p1->next;
}
}
}
void sort(linklist &L)
{
linklist p=L->next,q,r,t,k=L;
q=r=t=p; // 将指针初始化 指向第一个节点,不是头结点
if(L->next->next == NULL) // 只有一个节点不满足排序
;
else if(L->next == NULL) // 当链表为空
printf("链表为空!!!无数据!!");
else
while(p->next != NULL) // 采用的是p指针标识节点的变化
{
r=t=q=p; // 重新将指针复位
while(q->next != NULL) // 循环比较,将较小的标记下来
{
if(q->next->zs < t->zs)
{
t=q->next;
r=q;
}
q=q->next;
}
if(t != p) // 当标识的位置 不是第一个节点位置
{
if(t->next == NULL) // 如果当前位置是最后一个节点
{
k->next=t; // 将链表连接起来
k=k->next;
k->next=NULL; // 连接来的节点置空
r->next=NULL; // 原来的节点变成最后一个节点
}
else // 如果是中间的节点数据
{
r->next=t->next; // 将前一个节点以后一个节点相连
k->next=t; // 将排列好的链表接入节点
k=k->next;
k->next=NULL; // 将接入来的节点置空
}
}
else // 是第一个节点数据
{
k->next=t; // 将节点接入
k=k->next; // 指向接入的节点
p=t=r=q=p->next; // 重新调整起始节点位置
k->next=NULL; // 将接入的节点置空
}
if(p->next == NULL) // 指定的第一个节点 为空,则是最后一个数据 将其接入,break 跳出循环
{
k->next=p;
break;
}
} // 排序结束
}
void xb(linklist &L)
{
linklist p,q;
q=p=L->next; // 将p 指向第一个节点
q=q->next; // q指向第二个节点
while(q != NULL) // q不为空
{
if(p->zs == q->zs) // 前后两个幂相同,将相加的值存在最前的节点里,删除相同幂的节点
{
p->num=p->num+q->num;
p->next=q->next;
free(q);
q=p->next; // 将q重新指向下一个
}
else // 前后不相等
{
p=q; // 更新指针
q=q->next;
}
}
}
void createlist(linklist &L,char B) // 创建链表
{
linklist p,q;
char ch;
p=q=(linklist)malloc(sizeof(struct Node));
L->next=p; // 将头结点与下一个节点相链
printf("输入%c链表一个一元多项式的序数和幂:",B);
scanf("%f%d",&p->num,&p->zs);
p->next=NULL; // 将p1指向的节点指针置空,防止用户输入一个节点
printf("是否继续!(y/n):");
getchar();
ch=getchar();
while('Y' == ch || 'y' == ch)
{
p=(linklist)malloc(sizeof(struct Node));
printf("\n输入一个一元多项式的序数和幂:");
scanf("%f%d",&p->num,&p->zs);
q->next=p;
q=p;
printf("是否继续!(y/n):");
getchar();
ch=getchar();
}
q->next=NULL; // 将最后的节点的指针置空
p=L->next;
printf("你输入的多项式为:\n");
if(p != NULL)
{
if(p->zs != 1 && p->zs != 0)
{
printf("%f(X)%d",p->num,p->zs);
p=p->next;
}
else if(p->zs == 1)
{
printf("%f(X)",p->num);
p=p->next;
}
else
{
printf("%f",p->num);
p=p->next;
}
}
while(p!=NULL) // 遍历输出
{
if(p->num >= 0)
{
if(p->zs != 1 && p->zs != 0)
{
printf("+%f(X)%d",p->num,p->zs);
p=p->next;
}
else if(p->zs == 1)
{
printf("+%f(X)",p->num);
p=p->next;
}
else
{
printf("+%f",p->num);
p=p->next;
}
}
else
{
if(p->zs != 1 || p->zs != 0)
{
printf("%f(X)%d",p->num,p->zs);
p=p->next;
}else if(p->zs == 1)
{
printf("%f(X)",p->num);
p=p->next;
}else
{
printf("%f",p->num);
p=p->next;
}
}
}
printf("\n\n");
}
void chuli(linklist A,linklist &B) // 将B表作为修改表
{
linklist p,q,t,r,k;
t=A;
q=A->next;
r=B;
p=B->next;
while(p != NULL && q != NULL)
{
if(p->zs == q->zs) // 判断指数的大小
{
p->num=p->num+q->num; // 将序数相加
k=p;
p=p->next; // 指数相等时,将值相加 存入p指的位置里
t->next=q->next; // A链表中得相同指数的节点释放掉
free(q);
q=t->next; // q 依旧指向A 进行比较
r=r->next; // 在B中得插入位置也得变
}
else if(p->zs < q->zs) // B中得序数更小,指针移向后面的节点
{
k=p;
p=p->next;
r=r->next;
}
else if(p->zs > q->zs) // A 中的指数更大
{
t->next=q->next; // A中的头结点指针指向q节点的下一个节点
q->next=p; // 将A中的q节点链到B中来,完成插入
r->next=q; // B 中得两个节点 r指向的节点获取q 完成链表的插入
q=t->next; // q 依旧指向A中的节点
r=r->next; // 保持r位置与p位置相邻
}
}
if(p == NULL) // 如果修改表现为空则要将余下的的节点链接到p上,将节点保存在k中
k->next=q;
}
void fan(linklist &L) // 将链表倒置
{
linklist p,q,t;
t=p=L;
if(p->next == NULL) // 表为空
{
printf("表为空!!无数据!!");
getchar();
getchar();
exit(0);
}
q=L->next; // 不为空
if(q->next == NULL) // 只有一个节点不用操作
{
printf("\n只有一个节点数据!!!\n");
}
else // 两个以上的节点进行操作
{
p=q->next;
q->next=NULL; // 将第二个节点置空
while(p != NULL) // 将第三个及以后的节点依次往前插入
{
L->next=p; // 头结点链接要插入的节点
t=p->next; // t指向后一个等待插入的节点
p->next=q; // 将余下的节点链上
q=p; // 余下的节点位置向前移动
p=t; // p回溯到t指向的位置
}
}
}
void print(linklist L) // 打印输出
{
linklist p=L->next;
if(p)
{
printf("相加后的数据为:\n");
if(p->zs != 1 && p->zs != 0)
{
printf("%f(X)%d",p->num,p->zs);
p=p->next;
}
else if(p->zs == 1)
{
printf("%f(X)",p->num);
p=p->next;
}
else
{
printf("%f",p->num);
p=p->next;
}
while(p != NULL)
{
if(p->num >= 0)
{
if(p->zs != 1 && p->zs != 0)
{
printf("+%f(X)%d",p->num,p->zs);
p=p->next;
}
else if(p->zs == 1)
{
printf("+%f(X)",p->num);
p=p->next;
}
else
{
printf("+%f",p->num);
p=p->next;
}
}
else
{
if(p->zs != 1 && p->zs != 0)
{
printf("%f(X)%d",p->num,p->zs);
p=p->next;
}else if(p->zs == 1)
{
printf("%f(X)",p->num);
p=p->next;
}else
{
printf("%f",p->num);
p=p->next;
}
}
}
}
else
printf("\n表为空,无数据!!!!\n");
getchar();
getchar();
}
最后就是在主函数调用了,小弟费了3天才弄出来的!献给想编程的朋友
定义主函数文件名为main_4.cpp
#include"t11.h"
#include"f1.h"
#include"feilei.cpp"
void main()
{
linklist S,T; // 定义两个结构体指针
initfen(S); // 初始化
initfen(T);
createlist(S,'A'); // 创建链表
sort(S); // 对链表进行排
xb(S); // 将相同的数删去
createlist(T,'B');
sort(T);
xb(T);
chuli(S,T); // 对两个表做出处理
ListDelete(T,0); // 删除处理后表中为0的节点
fan(T);
print(T); // 打印输出
}
最后上传一张图吧!如果发现有错误,欢迎交流指正!