使用单链表实现多项式计算示例

 更新时间:2014年03月17日 09:37:17   作者:  
这篇文章主要介绍了使用单链表实现多项式计算示例,需要的朋友可以参考下

复制代码 代码如下:

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

//比较函数返回值
#define A_EQUAL_B  0
#define A_LARGE_B  1
#define A_LOWER_B -1

//错误返回之集合
#define SUCCESS            0
#define POINT_ARG_IS_NULL -1
#define LINKLIST_IS_NULL  -2
#define NOT_FOUND         -3

typedef struct
{
    int cst_term;//常数项
    int idx_term;//指数
}factor;

typedef factor data_t;
typedef struct linklist
{
 data_t data;
 struct linklist *next;
}linklist;

/*
 *
 * malloc头节点,头节点内的数据是无效的
 *
 */
linklist *creat_lnklst()
{
 linklist *head = (linklist *)malloc(sizeof(linklist));
 head->next = NULL;
 return head;
}

/*
 * pll是插入节点的前一项
 * data是数据
 * 为新节点分配内存,之后插入
 *
 */
int ins_head_lnklst(linklist *pll, const data_t *data)
{
 linklist *newnode = NULL;

 if(NULL == pll || NULL == data)
  return POINT_ARG_IS_NULL;

 newnode = (linklist *)malloc(sizeof(linklist));

 newnode->data = *data;

 newnode->next = pll->next;
 pll->next = newnode;

 return SUCCESS;
}

/*
 *
 * pll是要删除节点的前一个
 * data存放删除的数据
 * 检查pll是否是空
 * 检查链表是否为空
 * data是NULL就不用保存删除的数据
 *
 */
int del_head_lnklst(linklist *pll, data_t *data)
{
 linklist *tmp = NULL;

 if(NULL == pll)
  return POINT_ARG_IS_NULL;

 if(pll->next == NULL)
  return LINKLIST_IS_NULL;

 tmp = pll->next;

 if(NULL != data)
  *data = tmp->data;

 pll->next = tmp->next;

 free(tmp);

 return SUCCESS;
}

/*
 *
 * 内部支持data_t大小比较函数
 * 如果data_t修改成其他类型则需要修改此方法
 *
 */
static int cmp_data(const data_t *a, const data_t *b)
{
 int res = 0;

 if(a == NULL || b == NULL)
  return POINT_ARG_IS_NULL;

 res = a->idx_term - b->idx_term;
 if(res == 0)
  return A_EQUAL_B;
 else if(res > 0)
  return A_LARGE_B;
 else
  return A_LOWER_B;
}

/*
 *
 * 实现在链表中查找data匹配的前一项
 * compare是实现虚拟数据类型比较函数
 *
 */
linklist * locate_lnklst(linklist *pll, const data_t *data, int (*compare)(const data_t *, const data_t *))
{
 if(NULL == pll || data == NULL)
  return NULL;

 if(NULL == compare)
  compare = cmp_data;

 while(pll->next)
 {
  if(A_EQUAL_B == compare(&(pll->next->data), data))
   return pll;
  pll = pll->next;
 }

 return NULL;
}

/*
 *
 * 打印链表数据
 * 检查参数空指针
 * 检查空链表
 *
 */
int print_lnklst(linklist *pll)
{
 if(NULL == pll)
  return POINT_ARG_IS_NULL;

 if((pll = pll->next) == NULL)
 {
  printf("%s\n", "no element in linklist.\n");
  return LINKLIST_IS_NULL;
 }

 while(pll)
 {
        if(pll->next == NULL)
        {
      printf("%2d*X^%1d ", pll->data.cst_term, pll->data.idx_term);
        }
        else
        {
      printf("%2d*X^%1d +", pll->data.cst_term, pll->data.idx_term);
        }
  pll = pll->next;
 }
 printf("\n");

 return SUCCESS;
}

/*
 *
 * 删除对应数据的节点
 *
 */
int locate_del_lnklst(linklist *pll, const data_t *data)
{
 linklist *prev = NULL;

 if(NULL == pll || data == NULL)
  return POINT_ARG_IS_NULL;

 prev = locate_lnklst(pll, data, NULL);
 if(NULL == prev)
  return NOT_FOUND;

 return del_head_lnklst(prev, NULL);
}

int add_linklist(linklist *a, linklist *b)
{
    linklist *tmp;
    if(NULL == a || NULL == b)
        return POINT_ARG_IS_NULL;

    if((b = b->next) == NULL)
    {
        return LINKLIST_IS_NULL;
    }

    while(b != NULL)
    {
        tmp = locate_lnklst(a, &b->data, NULL);
        if(NULL == tmp)
            ins_head_lnklst(a, &b->data);
        else
            tmp->next->data.cst_term += b->data.cst_term;
        b = b->next;
    }
    return 0;
}

/*
 *
 * A = 1 + 2*X + 3*X^2
 * B = 4 + 5*X + 6*X^2
 * R = A + B
 *   = 5 + 7*X + 9*X^2
 *
 */
int init_a_b(linklist *a, linklist *b)
{
    factor tmp;
    tmp.cst_term = 1;
    tmp.idx_term = 0;
    ins_head_lnklst(a, &tmp);
    tmp.cst_term = 2;
    tmp.idx_term = 1;
    ins_head_lnklst(a, &tmp);
    tmp.cst_term = 3;
    tmp.idx_term = 2;
    ins_head_lnklst(a, &tmp);

    tmp.cst_term = 4;
    tmp.idx_term = 0;
    ins_head_lnklst(b, &tmp);
    tmp.cst_term = 5;
    tmp.idx_term = 1;
    ins_head_lnklst(b, &tmp);
    tmp.cst_term = 6;
    tmp.idx_term = 2;
    ins_head_lnklst(b, &tmp);
    return 0;
}
int main(int argc, const char *argv[])
{
 linklist *fml_a = creat_lnklst();
 linklist *fml_b = creat_lnklst();
    init_a_b(fml_a, fml_b);

    printf("A =");
    print_lnklst(fml_a);

    printf("B =");
    print_lnklst(fml_b);

    add_linklist(fml_a, fml_b);
    printf("A + B =");
    print_lnklst(fml_a);
 return 0;
}

相关文章

  • 详解c++中的trait与policy模板技术

    详解c++中的trait与policy模板技术

    trait模板和policy模板技术是把模板的trait和policy这两个针对不同具体类型有变化的方面抽离出来形成两个独立的模板。由于trait和policy本身是模板,它的行为是可配置的,在模板中通过组合或者以模板实参传进来的方式使用trait和policy,就可以配置出不同的具体实现
    2021-06-06
  • C语言实现翻译功能

    C语言实现翻译功能

    这篇文章主要为大家详细介绍了C语言实现简单的翻译功能,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2019-01-01
  • C语言 数据结构之链表实现代码

    C语言 数据结构之链表实现代码

    这篇文章主要介绍了C语言 数据结构之链表实现代码的相关资料,需要的朋友可以参考下
    2016-10-10
  • C语言中scanf的用法举例

    C语言中scanf的用法举例

    本节介绍输入函数 scanf 的用法,scanf 和 printf 一样,非常重要,而且用得非常多,所以一定要掌握,这篇文章主要介绍了C++中scanf的用法举例,需要的朋友可以参考下
    2022-11-11
  • C++第三方日志库Glog的安装与使用介绍

    C++第三方日志库Glog的安装与使用介绍

    这篇文章主要介绍了C++第三方日志库Glog的安装与使用介绍,本文配置所采用的环境为Visual Studio2017,本文通过图文并茂的形式给大家介绍的非常详细,需要的朋友可以参考下
    2022-02-02
  • C++异步数据交换实现方法介绍

    C++异步数据交换实现方法介绍

    这篇文章主要介绍了C++异步数据交换实现方法,异步数据交换,除了阻塞函数 send() 和 recv() 之外,Boost.MPI 还支持与成员函数 isend() 和 irecv() 的异步数据交换
    2022-11-11
  • 复数乘法中的结构体赋值实现代码

    复数乘法中的结构体赋值实现代码

    复数乘法中的结构体赋值实现代码。需要的朋友可以过来参考下,希望对大家有所帮助
    2013-10-10
  • C语言之实现辗转相除法的两种方式

    C语言之实现辗转相除法的两种方式

    这篇文章主要介绍了C语言之实现辗转相除法的两种方式,具有很好的参考价值,希望对大家有所帮助,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教
    2023-08-08
  • 变量定义与声明的区别详细解析

    变量定义与声明的区别详细解析

    外部变量(全局变量)的"定义"与外部变量的"声明"是不相同的,外部变量的定义只能有一次,它的位置是在所有函数之外,而同一个文件中的外部变量声明可以是多次的,它可以在函数之内(哪个函数要用就在那个函数中声明)也可以在函数之外(在外部变量的定义点之前)
    2013-09-09
  • C++实现日期类(Date)

    C++实现日期类(Date)

    这篇文章主要为大家详细介绍了C++实现日期类的相关代码,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2018-09-09

最新评论