您的位置:首页 > 其它

链表加法的两种实现

2015-10-27 20:18 281 查看
第一种是高位在链表尾部
a=7->1->2
b=4->3
result=1->5->2

没啥说的,注意进位,注意链表长度不一定一样


#include<stdio.h>
#include<stdlib.h>

/*Linkedlistnode*/
structnode
{
intdata;
structnode*next;
};

/*Functiontocreateanewnodewithgivendata*/
structnode*newNode(intdata)
{
structnode*new_node=(structnode*)malloc(sizeof(structnode));
new_node->data=data;
new_node->next=NULL;
returnnew_node;
}

/*FunctiontoinsertanodeatthebeginningoftheDoublyLinkedList*/
voidpush(structnode**head_ref,intnew_data)
{
/*allocatenode*/
structnode*new_node=newNode(new_data);

/*linktheoldlistoffthenewnode*/
new_node->next=(*head_ref);

/*movetheheadtopointtothenewnode*/
(*head_ref)=new_node;
}

/*Addscontentsoftwolinkedlistsandreturntheheadnodeofresultantlist*/
structnode*addTwoLists(structnode*first,structnode*second)
{
structnode*res=NULL;//resisheadnodeoftheresultantlist
structnode*temp,*prev=NULL;
intcarry=0,sum;

while(first!=NULL||second!=NULL)//whilebothlistsexist
{
//Calculatevalueofnextdigitinresultantlist.
//Thenextdigitissumoffollowingthings
//(i)Carry
//(ii)Nextdigitoffirstlist(ifthereisanextdigit)
//(ii)Nextdigitofsecondlist(ifthereisanextdigit)
sum=carry+(first?first->data:0)+(second?second->data:0);

//updatecarryfornextcalulation
carry=(sum>=10)?1:0;

//updatesumifitisgreaterthan10
sum=sum%10;

//Createanewnodewithsumasdata
temp=newNode(sum);

//ifthisisthefirstnodethensetitasheadoftheresultantlist
if(res==NULL)
res=temp;
else//Ifthisisnotthefirstnodethenconnectittotherest.
prev->next=temp;

//Setprevfornextinsertion
prev=temp;

//Movefirstandsecondpointerstonextnodes
if(first)first=first->next;
if(second)second=second->next;
}

if(carry>0)
temp->next=newNode(carry);

//returnheadoftheresultantlist
returnres;
}

//Autilityfunctiontoprintalinkedlist
voidprintList(structnode*node)
{
while(node!=NULL)
{
printf("%d",node->data);
node=node->next;
}
printf("\n");
}

/*Drierprogramtotestabovefunction*/
intmain(void)
{
structnode*res=NULL;
structnode*first=NULL;
structnode*second=NULL;

//createfirstlist7->5->9->4->6
push(&first,6);
push(&first,4);
push(&first,9);
push(&first,5);
push(&first,7);
printf("FirstListis");
printList(first);

//createsecondlist8->4
push(&second,4);
push(&second,8);
printf("SecondListis");
printList(second);

//Addthetwolistsandseeresult
res=addTwoLists(first,second);
printf("Resultantlistis");
printList(res);

return0;
}


第二种是高位在链表头部

a=2->1->7
b=3->4
result=2->5->1

这个为了处理进位,需要用递归的思想


//Arecursiveprogramtoaddtwolinkedlists

#include<stdio.h>
#include<stdlib.h>

//AlinkedListNode
structnode
{
intdata;
structnode*next;
};

typedefstructnodenode;

/*Autilityfunctiontoinsertanodeatthebeginningoflinkedlist*/
voidpush(structnode**head_ref,intnew_data)
{
/*allocatenode*/
structnode*new_node=(structnode*)malloc(sizeof(structnode));

/*putinthedata*/
new_node->data=new_data;

/*linktheoldlistoffthenewnode*/
new_node->next=(*head_ref);

/*movetheheadtopointtothenewnode*/
(*head_ref)=new_node;
}

/*Autilityfunctiontoprintlinkedlist*/
voidprintList(structnode*node)
{
while(node!=NULL)
{
printf("%d",node->data);
node=node->next;
}
printf("\n");
}

//Autilityfunctiontoswaptwopointers
voidswapPointer(node**a,node**b)
{
node*t=*a;
*a=*b;
*b=t;
}

/*Autilityfunctiontogetsizeoflinkedlist*/
intgetSize(structnode*node)
{
intsize=0;
while(node!=NULL)
{
node=node->next;
size++;
}
returnsize;
}

//Addstwolinkedlistsofsamesizerepresentedbyhead1andhead2andreturns
//headoftheresultantlinkedlist.Carryispropagatedwhilereturningfrom
//therecursion
node*addSameSize(node*head1,node*head2,int*carry)
{
//Sincethefunctionassumeslinkedlistsareofsamesize,
//checkanyofthetwoheadpointers
if(head1==NULL)
returnNULL;

intsum;

//Allocatememoryforsumnodeofcurrenttwonodes
node*result=(node*)malloc(sizeof(node));

//Recursivelyaddremainingnodesandgetthecarry
result->next=addSameSize(head1->next,head2->next,carry);

//adddigitsofcurrentnodesandpropagatedcarry
sum=head1->data+head2->data+*carry;
*carry=sum/10;
sum=sum%10;

//Assignethesumtocurrentnodeofresultantlist
result->data=sum;

returnresult;
}

//Thisfunctioniscalledafterthesmallerlistisaddedtothebigger
//lists'ssublistofsamesize.Oncetherightsublistisadded,thecarry
//mustbeaddedtoeleftsideoflargerlisttogetthefinalresult.
voidaddCarryToRemaining(node*head1,node*cur,int*carry,node**result)
{
intsum;

//Ifdiff.numberofnodesarenottraversed,addcarry
if(head1!=cur)
{
addCarryToRemaining(head1->next,cur,carry,result);

sum=head1->data+*carry;
*carry=sum/10;
sum%=10;

//addthisnodetothefrontoftheresult
push(result,sum);
}
}

//Themainfunctionthataddstwolinkedlistsrepresentedbyhead1andhead2.
//Thesumoftwolistsisstoredinalistreferredbyresult
voidaddList(node*head1,node*head2,node**result)
{
node*cur;

//firstlistisempty
if(head1==NULL)
{
*result=head2;
return;
}

//secondlistisempty
elseif(head2==NULL)
{
*result=head1;
return;
}

intsize1=getSize(head1);
intsize2=getSize(head2);

intcarry=0;

//Addsamesizelists
if(size1==size2)
*result=addSameSize(head1,head2,&carry);

else
{
intdiff=abs(size1-size2);

//Firstlistshouldalwaysbelargerthansecondlist.
//Ifnot,swappointers
if(size1<size2)
swapPointer(&head1,&head2);

//movediff.numberofnodesinfirstlist
for(cur=head1;diff--;cur=cur->next);

//getadditionofsamesizelists
*result=addSameSize(cur,head2,&carry);

//getadditionofremainingfirstlistandcarry
addCarryToRemaining(head1,cur,&carry,result);
}

//ifsomecarryisstillthere,addanewnodetothefronof
//theresultlist.e.g.999and87
if(carry)
push(result,carry);
}

//Driverprogramtotestabovefunctions
intmain()
{
node*head1=NULL,*head2=NULL,*result=NULL;

intarr1[]={9,9,9};
intarr2[]={1,8};

intsize1=sizeof(arr1)/sizeof(arr1[0]);
intsize2=sizeof(arr2)/sizeof(arr2[0]);

//Createfirstlistas9->9->9
inti;
for(i=size1-1;i>=0;--i)
push(&head1,arr1[i]);

//Createsecondlistas1->8
for(i=size2-1;i>=0;--i)
push(&head2,arr2[i]);

addList(head1,head2,&result);

printList(result);
getchar();
return0;
}



                                            
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: