数据结构——链表多项式加法合并

题目描述:
实现两个一元n次多项式的加法。例如P(A)=x+3x2-5x5+7,P(B)=2x2+6x3+x5-4x6,求P(A)+P(B)。

输入:每行是两个用空格隔开的整数m,n,分别代表多项式的系数和指数,以输入0 0作为结尾

输出:每次完成一个多项式的输入后,先输出该多项式;当第二个多项式输出完成后,下一行输出两个多项式输出的结果

(多项式打印的要求:  如果是第一项,不要打+号
            //如果不是第一项,且系数为正数,要打加号

            //如果系数为负数,系数自身带有符号

            //如果系数为1,不用打系数
            //系数为-1打印负号                           

            //如果系数不为1或-1,打印系数
            //如果指数为0,直接打系数不用打x^和指数
            //如果系数是-1或1,需要打1出来,不能只打符号

            //指数不为0
            //打印x
            //如果指数为1,不打指数,否则打指数)


这里对需要用到的函数进行说明:

数据结构——链表多项式加法合并_第1张图片

(1)数字转换为字符串函数itoa

 (2)字符串连接函数strcat

以两个字符串作为参数,把第2个字符串备份附加在第1个字符串末尾,并把拼接后形成的新的字符串作为第一个字符串,第二个字符串不变。

函数返回值 第一个字符串的地址

(3)字符串清空函数memset

memset(item,0,20);清空长20的字符串item


#include 
#include 

#include


typedef struct polynomial
{
	int coefficient;//系数
	int exp;//指数
	struct polynomial *next;//指针域	 
}*Link,Node ; //link指向多项式的结构体指针 ,node结构体变量
 
void inputPoly(Link head);//从控制台堕入链表的函数
void print(Link head); 
bool insert(Link head,int coefficient,int exp);//插入函数
void comlin2List(Link heada,Link headb,Link headab);//合并两个链表



void inputPoly(Link head)
{
	int coefficient,exp;//系数和指数
	printf("请输入系数和指数:");
	scanf("%d %d",&coefficient,&exp);
	while(coefficient!=0||exp!=0) 
	{
		insert(head,coefficient,exp);//掉函数输入多项式 
		printf("请输入系数和指数");
		scanf("%d %d",&coefficient,&exp); 
	 } 
}

bool insert(Link head,int coefficient,int exp)//保证指数是从大到小排列的 
{
	
	/*创建新节点*/ 
	Link newNode;//node指针指向新创建的节点
	Link q,p;//q,p两个节点一前一后
	p = head->next;
	q = head;//把q设为头节点,p为头结点的下一个 
	newNode = (Link)malloc(sizeof(Node));
	newNode->coefficient = coefficient;
	newNode->exp = exp;
//	int *new;
//  new=(int*) malloc(sizeof(int)); //不用int,直接用Node结构体变量 
//	new->coefficient=coefficient;//这样coefficient不在结构体内 
//	new->exp=exp;
	newNode->next=NULL;///缺了这一句,新的节点数据就显示不出了,指针域next域为null 
	
	/*插入*/ 
	if(p==NULL)//空表,插入第一个
	{
		q->next = newNode;
		newNode->next = NULL;//到尾了,指针域赋空值
		return true; 
	 } //大于当前指数 ,插在p前q后 
	 else if(exp>p->exp){
	 	q->next=newNode;
	 	newNode->next=p;
	 	return true;
	 }//小于当前指数,向后移动指针(保持p,q一前一后) 
	 else{
	    q=p;
	    p =p->next;//向后移动一位 
	 }
	 	 
}

/*打印链表多项式*/ 
void print(Link head) {
	Link p; //指向链表要输出的结点
	printf("多项式如下:\n");
	p = head->next;
 
	if (p == NULL) {  //多项式为空的情况 
		printf("多项式为空\n");
		return;
	}
	// 不是空表
	char item[20] = ""; //要打印的当前多项式的一项
	char number[7] = ""; //暂时存放系数转换成的字符串
	bool isFirstItem = true;//标志是否为第一个节点
	int flag = 0;  //只要进入过系数非0的情况,flag=1,判断就为false了,也就是不是第一项 
	//打印节点
	while (p != NULL) {
		memset(item, 0, 20); //清空字符串item,清空长20的字符串 
		itoa(p->coefficient, number, 10);//欲转换的字符串数据:系数,number目标字符串地址,转换进制10 
		if (p->coefficient == 0) {//当为0时的判断非常容易出错,系数为0 
			if (flag == 0) {
				isFirstItem = true;	//如果第一项系数为0,移动指针,判断仍为true
				p = p->next;
				continue;
			} else if (flag == 1) {//其他项系数为0,移动指针 
				p = p->next;
				continue;
			}
		} else {  //系数不为0 
			if (isFirstItem != true && p->coefficient > 0) {
				strcat(item, "+");//字符串的拼接,当前系数不为第一项,输出数字和加号 
			}
			if (p->coefficient == 1) {}//如果系数为1 ,则不用输出系数这块 
			else if (p->coefficient == -1) { //如果系数为-1,输出负号和数字 
				strcat(item, "-");
			} else if (p->coefficient != 0) { //如果系数非0,输出 
				strcat(item, number);//输出系数和多项式那箱 
			}
			if (p->exp == 1) {  //如果指数为1 
				strcat(item, "x");  //输出系数和x 
			} else if (p->exp == 0) {  //如果指数为0 
				if (p->coefficient == 1 || p->coefficient == -1)
					strcat(item, "1");//且系数为1或-1时,任何数的0次幂都为1 
			} else {  //如果指数为正常情况 
				strcat(item, "x^"); // 连接系数和x的指数 
				strcat(item, itoa(p->exp, number, 10)); //欲转换的字符串数据:指数,number目标字符串地址,转换进制10  
			}
			flag = 1; 
		}
		printf("%s", item); //打印当前节点代表的项
		p = p->next;//指向下个结点
		isFirstItem = false; //标志不是第一项了
	}
	printf("\n");
	return;
}

/*合并链表函数 */ 
void combin2List(Link heada, Link headb, Link headab) {
	Link pa, pb; //指向a,b链表和ab的指针
	pa = heada->next;
	pb = headb->next;
	while (pa != NULL && pb != NULL) { //a,b链表都没有没有访问完毕
		if (pa->exp > pb->exp) { //a的指数大于b的指数 
			insert(headab, pa->coefficient, pa->exp);//调用自定义函数insert() 
			pa = pa->next; //pa向后移一位 
		} else if (pa->exp < pb->exp) { //a的指数小于b 
			insert(headab, pb->coefficient, pb->exp); //调用 
			pb = pb->next;  //pb向后移一位 
		} else if (pa->exp == pb->exp) { //a,b指数相同 
			int coefficient;
			coefficient = pa->coefficient + pb->coefficient; //合并,合并后的系数为a,b之和 
			insert(headab, coefficient, pa->exp);
			pa = pa->next;
			pb = pb->next;
		}
		//如果指数a>指数b,a节点插入ab链表,a指针后移
		//如果指数a<指数b,b节点插入ab链表,b指针后移
		//如果指数a==指数b,a、b系数相加,插入ab链表,a、b指针后移
	}
	//如果a、b链表还有尾巴,将它加到ab链表后面
	while (pa != NULL) {
		insert(headab, pa->coefficient, pa->exp);
		pa = pa->next;
	}
	while (pb != NULL) {
		insert(headab, pb->coefficient, pb->exp);
		pb = pb->next;
	}
	return;

}

/*清空链表函数*/ 
void clearLink(Link head) {
	Link p, q;
	if (head == NULL)
		return;
	q = head->next;
	free(head); //释放head 
	while (q != NULL) {
		p = q;
		q = q->next;
		free(p);
	}
 
}

/*主函数*/
int main() {
	Link headA, headB; //两个多项式的头指针
	Link headAB;//合并后的多项式的头指针
 
	/*链表的初始化*/
	headA = (Link)malloc(sizeof(Node));
	headA->next = NULL;
	headB = (Link)malloc(sizeof(Node));
	headB->next = NULL;
	headAB = (Link)malloc(sizeof(Node));
	headAB->next = NULL;
 
	printf("请输入第一个多项式的系数和指数,以(0 0)结束:\n");
	inputPoly(headA);
	printf("第一个");
	print(headA);
	printf("请输入第二个多项式的系数和指数,以(0 0)结束:\n");
	inputPoly(headB);
	printf("第二个");
	print(headB);
 
	combin2List(headA, headB, headAB);
	printf("合并后");
	print(headAB);
	clearLink(headA);
	clearLink(headB);
	clearLink(headAB);
	return 0;
} 






你可能感兴趣的:(数据结构,链表,数据结构)