链表实现大数相加和大数相乘

全部c代码如下

#include
#include

#define ElemType int
#define HUNTHOU 10000

typedef struct LNode  //链表节点
{
 ElemType data;
 struct LNode *next;
}ListNode, *LinkedList;

int InitList(LinkedList &list) //构造一个空的线形表list
{

 list = (LinkedList)malloc(sizeof(ListNode));
 if(!list)
 {
  exit(-1); //堆分配失败
 }

 list->data = -1;
 list->next = NULL;

 return 0;
}

int DestroyList(LinkedList &list) //销毁线性表list
{

 ListNode * node=NULL; 
 if(list)
 {
 do
 {
  node = list->next;
  free(list);
  list = node;  
 }while(list);
 }

 return 0;
}

int GetElem(LinkedList list, int index, ElemType &e)//获得list第index个节点,用e返回
{
 ListNode *p=list->next;
 int j =1;

 while( p && j {
  p=p->next;
  ++j;
 }

 if(!p || j>index) //index不合法
 {
  return -1;
 }

 e=p->data;
 return 0;
}

int ListInsert(LinkedList &list, int index, ElemType e)//向list第index位置之前插入e
{
 ListNode *p=list;
 int j =0;

 while( p && j {
  p=p->next;
  ++j;
 }

 if(!p || j>index-1) //index不合法
 {
  return -1;
 }

 ListNode *n =(ListNode*) malloc( sizeof(ListNode) );
 if(!n)
 {
  exit(-1);
 }
 n->data = e;   //生成节点
 n->next = p->next;
 
 p->next = n;
 return 0;
}

int ListTraverse(LinkedList list, int(*Visit)(ElemType e), int tag)//遍历list,对每个数据元素调用visit
{
 LinkedList p =list->next;
 if(tag==1)   //顺序访问
 {
  while(p)
  {
   Visit(p->data);
   p=p->next;
  }
  return 0;
 }
 else if(tag==0) //逆续访问
 {
  int i = 0;
  while(p)
  {
   ++i;
   p=p->next;
  }

  while(i>0)
  {
   ElemType e;
   GetElem(list,i--,e);
   Visit(e);
  }
  return 0;
 }
 else
 {
  return -1;
 }
}

void Input(LinkedList &list) //输入大数,转换按标准形式存储
{
 //printf("输入大的正整数……/n");
 char c;
 LinkedList l;
 InitList(l);
 while( (c=getchar()) != '/n')
 {
  if(c>='0' && c<= '9')
  {
   ListInsert(l,1,c-'0');//c-'0'  逆续存入临时链表
  }
 }
 
 LinkedList p=l->next;
 int last=1;
 while(p) //转换存储方式
 {
  int a[4]={0};
  for(int i=0; i<4; i++)
  {
   a[i] = p->data;
   p=p->next;
   if(!p) break;
  }
  int temp = a[0] + a[1]*10 + a[2]*100 + a[3]*1000;
  ListInsert(list,last++,temp);//总是将temp插入list末尾
 }

 DestroyList(l);
}

int AddHuge(LinkedList list1,LinkedList list2,LinkedList &result)//result=list1+list2  大数相加
{
 ListNode *p,*q,*r;
 LinkedList t1=NULL,t2=NULL;

 if(list1 == result)//若list1与result相同
 {  
  InitList(t1);
  int i=0;
  p=list1->next;
  while(p)
  {
   ListInsert(t1,++i,p->data);
   p=p->next;
  }
  p=t1->next;
 }
 else
 {
  p=list1->next;
 }

 if(list2 == result)//若list2与result相同
 {  
  InitList(t2);
  int i=0;
  q=list2->next;
  while(q)
  {
   ListInsert(t2,++i,p->data);
   q=q->next;
  }
  q=t2->next;
 }
 else
 {
  q=list2->next;
 }
 
 if(result->next)//清空result
 {
  DestroyList(result);
  InitList(result);
 }

 int total=0,carry=0,number=0;
 int i = 0;

 while(p && q)
 {
  total = p->data + q->data + carry;
  number = total % HUNTHOU;
  carry = total / HUNTHOU;
  ListInsert(result,++i,number);//插入到末尾
  p=p->next;
  q=q->next;
 }

 r=(p)?p:q;
 while(r)
 {
  total = r->data + carry;
  number = total % HUNTHOU;
  carry = total / HUNTHOU;
  ListInsert(result,++i,number);//插入到末尾
  r=r->next;
 }
 
 if(carry>0)
 {
  ListInsert(result,++i,carry);//插入到末尾
 }
 
 DestroyList(t1);
 DestroyList(t2);
 return 0;
}

int HugeMulInt(LinkedList list, int num, LinkedList &result) //大数乘小正整数
{
 ListNode *p=NULL;
 LinkedList t1 = NULL;
 
 int number=0,carry=0,total=0;
 int i=0;

 if(list == result)
 {  
  InitList(t1);
  int j=0;
  p=list->next;
  while(p)
  {
   ListInsert(t1,++j,p->data);
   p=p->next;
  }
  p=t1->next;
 }
 else
 {
  p=list->next;
 }

 if(result->next)
 {
  DestroyList(result);
  InitList(result);
 }

 while(p)
 {
  total = num * p->data + carry;
  number = total % HUNTHOU;
  carry = total / HUNTHOU;
  ListInsert(result,++i,number);//插入到末尾

  p=p->next;
 }

 if(carry>0)
 {
  ListInsert(result,++i,carry);//插入到末尾
 }
 
 DestroyList(t1);
 return 0;
}

int PrintNum(ElemType e)//打印链表节点
{
 if(e<=9)
 {
  printf("000%d",e);
 }
 else if(e<=99)
 {
  printf("00%d",e);
 }
 else if(e<=999)
 {
  printf("0%d",e);
 }
 else
 {
  printf("%d",e);
 }

 return 0;
}


int HugeMultiply(LinkedList list1, LinkedList list2, LinkedList &result)//大数相乘
{
 ListNode *p=NULL,*p1=NULL,*q1=NULL;
 LinkedList temp1,t1=NULL,t2=NULL;
 InitList(temp1);

 if(list1 == result) //若list1与result相同,创建临时链表
 {  
  InitList(t1);
  int j=0;
  p=list1->next;
  while(p)
  {
   ListInsert(t1,++j,p->data);
   p=p->next;
  }
  list1=t1;
 }

 if(list2 == result) //若list2与result相同,创建临时链表
 {  
  InitList(t2);
  int j=0;
  p=list2->next;
  while(p)
  {
   ListInsert(t2,++j,p->data);
   p=p->next;
  }
  list2=t2;
 }
 
 if(result->next)//初始化result
 {
  DestroyList(result);
  InitList(result);
 }

 p = list2->next;   //p指向list2第一个节点
 
 int i=0;
 while(p)
 {
  for(int a=0,b=0;a<4;a++)
  {
   if(a==0) //取个位
   {
    b = p->data % 10;
   }
   else if(a==1)  //取十位
   {
    b=(p->data % 100)/10;
   }
   else if(a==2)  //百位
   {
    b=(p->data % 1000)/100;
   }
   else if(a==3)
   {
    b=(p->data % 10000)/1000;
   }

   HugeMulInt(list1,b,temp1);//相乘

   for(int j=0;j   {
    HugeMulInt(temp1,10,temp1);
   }

   AddHuge(result,temp1,result); //相加
   i++;
  }
  p=p->next;
  
 }

 DestroyList(temp1);
 DestroyList(t1);
 DestroyList(t2);

 return 0;
}


void main()
{
 LinkedList list1,list2,list3,result;
 InitList(list1);
 InitList(list2);
 InitList(list3);
 InitList(result);

 printf("Input NUM1: ");
 Input(list1);

 printf("/nInput NUM2: ");
 Input(list2);

 AddHuge(list1,list2,result);
 printf("/nlist1 加 list2 的结果 :/t");
 ListTraverse(result, PrintNum,0);
 printf("/n");

 HugeMultiply(list1,list2,result);
 printf("NUM1 乘 NUM2 的结果 RESULT:/t");
 ListTraverse(result, PrintNum,0);
 printf("/n");
 
 HugeMultiply(result,result,result);
 printf("RESULT 乘 RESULT 的结果 :/t");
 ListTraverse(result, PrintNum,0);
 printf("/n/n/n");

 DestroyList(list1);
 DestroyList(list2);
 DestroyList(list3);
 DestroyList(result);
}

你可能感兴趣的:(链表实现大数相加和大数相乘)