單鏈表實現多項式相加
阿新 • • 發佈:2018-12-15
這個小專案用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;
}