1. 程式人生 > >單鏈表實現多項式相加

單鏈表實現多項式相加

這個小專案用C語言實現 程式碼中有我的註釋

程式碼:

//mylist.h
#pragma once

typedef int DataType;
typedef char Variate;


typedef struct Node{
  DataType _elem; //項的係數
  Variate _ch;  //規定'#'表示此項為常數項
  int _power; //項的次方
  struct Node* _next;
}Node, *PNode;

//初始化連結串列
void ListInit(PNode* head);
//新增節點
//--返回值說明--
//1 :成功
//0 :失敗
int ListAdd
(PNode* head, DataType elem, Variate ch, int Power);
//mylist.c
#include <stdio.h>
#include <assert.h>
#include "mylist.h"

//初始化連結串列
void ListInit(PNode* head){
  assert(head);
  *head = NULL;
}
//新增節點
int ListAdd(PNode* head, DataType elem, Variate ch, int Power){
  assert(head);
  if(NULL ==
*head){ *head = (PNode)malloc(sizeof(Node)); (*head)->_elem = elem; (*head)->_ch = ch; (*head)->_power = Power; (*head)->_next = NULL; }else{ PNode tmp = *head; while(tmp->_next != NULL){ tmp = tmp->_next; } tmp->_next = (PNode)malloc
(sizeof(Node)); tmp->_next->_elem = elem; tmp->_next->_ch = ch; tmp->_next->_power = Power; tmp->_next->_next = NULL; } return 1; }
//main.c
#include <stdio.h>
#include "mylist.c"

/*
 * 1. 規定只能表示式只能計算 +/- 運算
 * 2. 規定常數項的次數只能是1
 */

void ExpressionPrint(PNode list){
  assert(list);
  PNode tmp = list;
  while(tmp != NULL){
  	//如果當前項係數大於零且不為表示式首項,列印加號(注意格式控制,加號前有空格)
    if(tmp->_elem > 0 && tmp != list){
      printf(" +");
    }
    //如果變數的次數不為1
    if(tmp->_ch != '#' && tmp->_power != 1){
      printf(" %d%c^%d", tmp->_elem, tmp->_ch, tmp->_power);
    }//如果變數的次數為1,則不列印該項變數的次數
    else if(tmp->_ch != '#' && tmp->_power == 1){
      printf(" %d%c", tmp->_elem, tmp->_ch);
    }//輸出常量
    else if(tmp->_ch == '#'){
      printf(" %d", tmp->_elem);
    }
    tmp = tmp->_next;
  }//end while(tmp != NULL)
  printf("\n");
}

PNode ExpressionAdd(PNode list1, PNode list2){
  if(list1 == NULL){
    return list2;
  }
  if(list2 == NULL){
    return list1;
  }
  //拿著連結串列1中的項遍歷連結串列2中的項
  PNode tmp1 = list1;
  PNode tmp2 = list2;
  PNode new_list;
  ListInit(&new_list);//一定不能忘記初始化連結串列!
  while(tmp1 != NULL){
    while(tmp2 != NULL){
      //如果連結串列1當前項和連結串列2項匹配,則將兩者的係數相加並新增到新連結串列
      if(tmp1->_ch == tmp2->_ch && tmp1->_power == tmp2->_power){
        ListAdd(&new_list, tmp1->_elem + tmp2->_elem, 
        		tmp1->_ch, tmp1->_power);
        break;
      }
      tmp2 = tmp2->_next;
    }//end while(tmp2 != NULL)
    //如果沒找到相同型別的項,則將連結串列1中的項新增到新連結串列中
    if(NULL == tmp2){
      ListAdd(&new_list, tmp1->_elem, tmp1->_ch, tmp1->_power);
    }//end while(tmp1 != NULL)
    tmp1 = tmp1->_next;//指向連結串列1的指標向後走
    tmp2 = list2;//讓指向連結串列2的指標重新指向連結串列2的頭部
  }
  PNode tmp3 = new_list;
  //將連結串列2中沒有新增到新連結串列中的項找出來新增到新連結串列
  while(tmp2 != NULL){
    while(tmp3 != NULL){
      //如果在新連結串列中找到了相同型別的項,則退出迴圈
      if(tmp2->_ch == tmp3->_ch && tmp2->_power == tmp3->_power){
        break; 
      }
      tmp3 = tmp3->_next;
    }//end while(tmp3 != NULL)
    //如果在新連結串列中沒有找到相同型別的項,則將連結串列2的當前項新增到新連結串列
    if(NULL == tmp3){
      ListAdd(&new_list, tmp2->_elem, tmp2->_ch, tmp2->_power);
    }
    tmp2 = tmp2->_next;
    tmp3 = new_list;//將指向新連結串列的指標重新指向新連結串列的頭部
  }//end while(tmp2 != NULL)
  return new_list;
}

//測試用例
//由於我在實現的時候已經把一些特殊情況考慮到,所以這裡的測試用例只是簡單的
//看一下實現後的效果
int main() {
  PNode list_1;
  ListInit(&list_1);
  ListAdd(&list_1, 3, 'x', 29);
  ListAdd(&list_1, -2, 'x', 12);
  ListAdd(&list_1, 3, '#', 1);
  ExpressionPrint(list_1);
  PNode list_2;
  ListInit(&list_2);
  ListAdd(&list_2, 5, 'x', 29);
  ListAdd(&list_2, 4, 'x', 20);
  ListAdd(&list_2, 1, 'x', 2);
  ListAdd(&list_2, 12, '#', 1);
  ExpressionPrint(list_2);
  PNode result = ExpressionAdd(list_1, list_2);
  ExpressionPrint(result);
  return 0;
}