0
点赞
收藏
分享

微信扫一扫

实例:多项式加法

JakietYu 2022-05-05 阅读 61

1.老师的代码

        1.1结构体


typedef struct LinkNode{
    int coefficient;
    int exponent;
    struct LinkNode *next;
}*LinkList,*NodePtr;

        1.2初始化


LinkList initLinkList(){
    LinkList tempHeader=(LinkList)malloc(sizeof(struct LinkNode));
    tempHeader->coefficient=0;
    tempHeader->exponent=0;
    tempHeader->next=NULL;
    return tempHeader;
}

        1.3打印链表或结点


void printList(LinkList paraHeader){
    NodePtr p=paraHeader->next;
    while(p!=NULL){
        printf("%d * 10^%d +",p->coefficient,p->exponent);
        p=p->next;
    }
    printf("\r\n");
}


void printNode(NodePtr paraPtr,char paraChar){
    if(paraPtr==NULL){
        printf("NULL\r\n");
    } else{
        printf("The element of %c is (%d * 10^%d)\r\n",paraChar,paraPtr->coefficient,paraPtr->exponent);
    }
}

        1.4添加元素(尾部依次添加)


void appendElement(LinkList paraHeader,int paraCoefficient,int paraExponent){
    NodePtr p,q;
    
    q=(NodePtr)malloc(sizeof(struct LinkNode));
    q->coefficient=paraCoefficient;
    q->exponent=paraExponent;
    q->next=NULL;
    
    p=paraHeader;
    while(p->next!=NULL){
        p=p->next;
    }
    
    p->next=q;
}

        1.5加法函数(运行时出现问题)


void add(NodePtr paraList1,NodePtr paraList2){
    NodePtr p,q,r,s;
    
    p=paraList1->next;
    printNode(p,'p');
    q=paraList2->next;
    printNode(q,'q');
    r=paraList1;
    printNode(r,'r');
    free(paraList2);

    while((p!=NULL)&&(q!=NULL)){
        if(p->exponent < q->exponent){
            printf("Case 1\r\n");
            r=p;
            printNode(r,'r');
            p=p->next;
            printNode(p,'p');
        } else if(p->exponent > q->exponent){
            printf("Case 2\r\n");
            r->next=q;
            r=q;
            printNode(r,'r');
            q=q->next;
            printNode(q,'q');
        } else{
            printf("Case 3\r\n");
            p->coefficient=p->coefficient + q->coefficient;
            printf("The coefficient is %d.\r\n",p->coefficient);
            if(p->coefficient==0){
                printf("Case 3.1\r\n");
                s=p;
                p=p->next;
                printNode(p,'p');
                free(s);
            } else{
                printf("Case 3.2\r\n");
                r=p;
                printNode(r,'r');
                p=p->next;
                printNode(p,'p');
            }// if small
            s=q;
            q=q->next;
            free(s);
        }// if big

        printf("p=%ld,q=%ld\r\n",p,q);
    }// while

    printf("End of while.\r\n");
    
    if(p==NULL){
        r->next=q;
    } else {
        r->next=p;
    }

    printf("Addition ends.\r\n");
}

        1.5.1不改变测试案例

         1.5.2改变测试案例

将多项式2中-9改成9时,出现了壮观的一幕

 程序进入了死循环,不停刷屏。 

        1.6测试函数

void additionTest(){
	
    LinkList tempList1=initLinkList();
    appendElement(tempList1,7,0);
    appendElement(tempList1,3,1);
    appendElement(tempList1,9,8);
    appendElement(tempList1,5,17);
    printList(tempList1);

    LinkList tempList2=initLinkList();
    appendElement(tempList2,8,1);
    appendElement(tempList2,22,7);
    appendElement(tempList2,-9,8);
    printList(tempList2);

    add(tempList1,tempList2);
    printList(tempList1);
}

2.自己的代码

        2.1 add函数,此处按照自己的思路写


void add(Listptr plist1,Listptr plist2){
	Nodeptr p,q,r,s,m; /*添加,s为p的前驱,m为删除辅助指针*/
	p=plist1->next;q=plist2->next;
	s=plist1,m=plist2;
	
    /*当p,q皆不指向空时进入while循环*/

	while((p!=NULL)&&(q!=NULL)){

        /*第一种情况,p指向的指数小于q指向的指数时,p指向下一个结点*/

		if(p->exponent < q->exponent){
			printf("Case 1\n");
			s=s->next;    /*前驱同时后移*/
			p=p->next;
		}

        /*第二种情况,p指向的指数大于q指向的指数,将q指向的结点插入链表1中*/

		else if(p->exponent > q->exponent){
			printf("Case 2\n");
			r=(Nodeptr)malloc(sizeof(struct Linknode));
			r->coefficient=q->coefficient;
			r->exponent=q->exponent;
			
			r->next=p;
			s->next=r;   //s 为前驱 
			s=r;        /*前驱后移,此时p不用后移,p在此后还有可能遇到指数相同的项*/
			m=q;
			q=q->next;    /*q后移,释放已计算的p结点*/
			free(m);
		}

        /*第三种情况,p,q指向的指数相等*/

		else{
			printf("Case 3\n");
            p->coefficient=p->coefficient + q->coefficient;

            /*运算后系数为0,删除链表1中p指向的结点*/
            if(p->coefficient==0){
            	printf("Case 3.1 相等\n");

            /*s 为前驱,此时s不用移动,p结点删除后,s仍为前驱,此处仅改变s的next指向*/
            	s->next=p->next;  
            	m=p;p=p->next;    /*释放已计算p结点*/
            	free(m);
			}
            
            /*运算后系数不为0,p后移*/
			else{
				printf("Case 3.2 不相等\n");
				s=s->next;    /*前驱和p同时后移*/
				p=p->next;
			}
			m=q;    /*释放已计算q结点*/
			q=q->next;
			free(m);
		}
	}
	
    /*p指向空时,将q表连接到p表;
        q指向空时,则说明已经过以上操作计算完,无需再做处理*/
	if(p==NULL){
		s->next=q;
	}

}

     例:

第一步:s指向Header1,p,q指向第一个结点

  

 第二步:前两个结点都为情况1(p的指数小于q),所以循环到情况2(p的指数大于q)

 第三步:将q指向的结点插入链表1,s后移,p不动,之后为情况3中第二种

 

 第四步:相加后保留p指向的结点,释放q指向的结点;s,p,q均往后移动,之后为情况三中第一种

 第五步:删除p指向的结点,s不动,p后移,q后移

 第六步:将q指向的结点加入链表1,s后移(图中未画出),q指向NULL,结束

        2.2 GET函数,基本和单链表一致


void get(Listptr pHeader,int pPosition){
    //判断输入是否合法
	if(pPosition<0){
		printf("ERROR! 请输入一个大于零的数!\n");
		//return '\0';
	} //attention
	
    //通过循环定位p
	Nodeptr p=pHeader;
	int i;
	for(i=0;i<pPosition;++i){
		p=p->next;

        //若超过链表长度,输出原因并退出
		if(p==NULL){
			printf("ERROR! 超过限度!\n");
			//return'\0';
		}	
	}
	 
    //一切正常,输出该节点的值
	printf("%d is (%d * 10^%d)\n",pPosition,p->coefficient,p->exponent);
}

       结果为输出结点值。

        2.3 LOCATE函数,也基本和单链表一致


Nodeptr locate(Listptr pHeader,int pcoefficient,int pexponent){
	Nodeptr p=pHeader;

    //通过循环定位p
	while((p->next!=NULL)&&(p->next->coefficient!=pcoefficient)&&(p->next->exponent!=pexponent)){
		p=p->next;		
	}
	
    //若未找到,输出原因,退出程序
	p=p->next;
	if(p==NULL){
			printf("ERROR! 未找到!\n");
			return 0;
	}
		
    //一切正常,返回p
	return p;
} 

       结果为返回P指针。

        2.4 test函数


void Test(){
	

    /*第一组数据测试,涵盖所有情况*/
	Listptr t=init();Listptr tt=init();
	printf("TEST 1 初始化 :\n");
	printlist(t);printlist(tt);
	
	printf("TEST 1 :\n");
	append(t,5,0);
	append(t,12,1);
	append(t,3,7);
	append(t,4,10);
	append(t,8,15);
	printlist(t);
	

    /*中间穿插的GET测试*/
	printf("GET TEST :\n");
	get(t,2);
	
    /*中间穿插的LOCATE测试*/
	printf("LOCATE TEST :\n");
	Nodeptr l=locate(t,4,10);
	printf("LOCATE is %ld\n",l);
	

	printf("TEST 1 链表 2 :\n");
	append(tt,4,3);
	append(tt,4,7);
	append(tt,-4,10);
	append(tt,2,12);
	printlist(tt);

	printf("TEST 1 ADD BEGIN :\n");
	add(t,tt);
	printlist(t);
	
	
    /*第二组数据测试,常规情况*/
	Listptr g=init();Listptr gg=init();
	printf("TEST 2 初始化 : \n");
	printlist(g);printlist(gg);
	
	printf("TEST 2 :\n");
	append(g,2,3);
	append(g,4,5);
	append(g,3,10);
	append(g,2,12);
	printlist(g);
	
	printf("TEST 2 链表 2 :\n");
	append(gg,4,3);
	append(gg,-2,5);
	append(gg,5,10);
	append(gg,-1,12);
	append(gg,5,14);
	printlist(gg);
	
	printf("TEST 2 ADD BEGIN :\n");
	add(g,gg);
	printlist(g);
	

    /*第三组数据测试,为空*/
	printf("TEST 3 NULL :\n");
	Listptr e=init();Listptr ee=init();
	printf("TEST 3 ADD BEGIN :\n");
	add(e,ee);
	printlist(e);
	

    /*第四组数据测试,刚好相抵消*/
	printf("TEST 4 FULL :\n");
	Listptr s=init();Listptr ss=init();
	
	append(s,3,1);
	append(s,-5,3);
	printlist(s);
	
	printf("TEST 4 链表 2 :\n");
	append(ss,-3,1);
	append(ss,5,3);
	printlist(ss);
	
	printf("TEST 4 ADD BEGIN :\n");
	add(s,ss);
	printlist(s);
		
	printf("END\n");
	
}

        2.5完整代码及运行结果

#include <stdio.h>
#include <malloc.h>

typedef struct Linknode{
	int coefficient;
	int exponent;
	struct Linknode *next;
}*Listptr,*Nodeptr;

Listptr init(){
	Listptr tHeader=(Listptr)malloc(sizeof(struct Linknode));
	
	tHeader->coefficient=0;
	tHeader->exponent=0;
	tHeader->next=NULL;
	
	return tHeader;
}

void printlist(Listptr pHeader){
    Nodeptr p=pHeader->next;
    while(p!=NULL){
        printf("%d * 10^%d +",p->coefficient,p->exponent);
        p=p->next;
    }
    printf("\r\n");
}

void printnode(Nodeptr p,char pChar){
    if(p==NULL){
    	printf("%c is NULL\n",pChar);
	}
	else{
		printf("%c is (%d * 10^%d)\n",pChar,p->coefficient,p->exponent);
	}
}
	
void append(Listptr pHeader,int pcoefficient,int pexponent){
	Nodeptr p,q;
	
	q=(Nodeptr)malloc(sizeof(struct Linknode));
	q->coefficient=pcoefficient;
	q->exponent=pexponent;
	q->next=NULL;
	
	p=pHeader; 
	while(p->next!=NULL)
		p=p->next;
		
	p->next=q;	
}

void add(Listptr plist1,Listptr plist2){
	Nodeptr p,q,r,s,m;//r添加,s为p的前驱,m为删除辅助指针 
	p=plist1->next;q=plist2->next;
	s=plist1,m=plist2;
	
	while((p!=NULL)&&(q!=NULL)){
		if(p->exponent < q->exponent){
			printf("Case 1\n");
			s=s->next;
			p=p->next;
		}
		else if(p->exponent > q->exponent){
			printf("Case 2\n");
			r=(Nodeptr)malloc(sizeof(struct Linknode));
			r->coefficient=q->coefficient;
			r->exponent=q->exponent;
			
			r->next=p;
			s->next=r;//s 为前驱 
			s=r;
			m=q;
			q=q->next;
			free(m);
		}
		else{
			printf("Case 3\n");
            p->coefficient=p->coefficient + q->coefficient;
            if(p->coefficient==0){
            	printf("Case 3.1 相等\n");
            	s->next=p->next;//s 为前驱 
            	m=p;p=p->next;
            	free(m);
			}
			else{
				printf("Case 3.2 不相等\n");
				s=s->next;
				p=p->next;
			}
			m=q;
			q=q->next;
			free(m);
		}
	}
	
	if(p==NULL){
		s->next=q;
	}

}

void get(Listptr pHeader,int pPosition){
	if(pPosition<0){
		printf("ERROR! 请输入一个大于零的数!\n");
		//return '\0';
	} //attention
	
	Nodeptr p=pHeader;
	int i;
	for(i=0;i<pPosition;++i){
		p=p->next;
		if(p==NULL){
			printf("ERROR! 超过限度!\n");
			//return'\0';
		}	
	}
	 
	printf("%d is (%d * 10^%d)\n",pPosition,p->coefficient,p->exponent);
}


Nodeptr locate(Listptr pHeader,int pcoefficient,int pexponent){
	Nodeptr p=pHeader;

	while((p->next!=NULL)&&(p->next->coefficient!=pcoefficient)&&(p->next->exponent!=pexponent)){
		p=p->next;		
	}
	
	p=p->next;
	if(p==NULL){
			printf("ERROR! 未找到!\n");
			return 0;
	}
		
	return p;
} 


void Test(){
	
	Listptr t=init();Listptr tt=init();
	printf("TEST 1 初始化 :\n");
	printlist(t);printlist(tt);
	
	printf("TEST 1 :\n");
	append(t,5,0);
	append(t,12,1);
	append(t,3,7);
	append(t,4,10);
	append(t,8,15);
	printlist(t);
	
	printf("GET TEST :\n");
	get(t,2);
	
	printf("LOCATE TEST :\n");
	Nodeptr l=locate(t,4,10);
	printf("LOCATE is %ld\n",l);
	
	printf("TEST 1 链表 2 :\n");
	append(tt,4,3);
	append(tt,4,7);
	append(tt,-4,10);
	append(tt,2,12);
	printlist(tt);

	printf("TEST 1 ADD BEGIN :\n");
	add(t,tt);
	printlist(t);
	
	
	Listptr g=init();Listptr gg=init();
	printf("TEST 2 初始化 : \n");
	printlist(g);printlist(gg);
	
	printf("TEST 2 :\n");
	append(g,2,3);
	append(g,4,5);
	append(g,3,10);
	append(g,2,12);
	printlist(g);
	
	printf("TEST 2 链表 2 :\n");
	append(gg,4,3);
	append(gg,-2,5);
	append(gg,5,10);
	append(gg,-1,12);
	append(gg,5,14);
	printlist(gg);
	
	printf("TEST 2 ADD BEGIN :\n");
	add(g,gg);
	printlist(g);
	
	printf("TEST 3 NULL :\n");
	Listptr e=init();Listptr ee=init();
	printf("TEST 3 ADD BEGIN :\n");
	add(e,ee);
	printlist(e);
	
	printf("TEST 4 FULL :\n");
	Listptr s=init();Listptr ss=init();
	
	append(s,3,1);
	append(s,-5,3);
	printlist(s);
	
	printf("TEST 4 链表 2 :\n");
	append(ss,-3,1);
	append(ss,5,3);
	printlist(ss);
	
	printf("TEST 4 ADD BEGIN :\n");
	add(s,ss);
	printlist(s);
		
	printf("END\n");
	
}

void main(){
	Test();
}

        运行结果如图

 

 

举报

相关推荐

0 条评论