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

代码如下:

#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;
}

(0)

相关推荐

  • 用C语言实现单链表的各种操作(二)

    上一篇文章<用C语言实现单链表的各种操作(一)>主要是单链表的一些最基本的操作,下面,主要是一些其他的典型的算法和测试程序. 复制代码 代码如下: /* 对单链表进行排序处理*/struct LNode *sort(struct LNode *head){  LinkList *p;  int n,i,j;  int temp;  n = ListLength(head);  if(head == NULL || head->next == NULL)    return head; 

  • C语言单链表常见操作汇总

    C语言的单链表是常用的数据结构之一,本文总结了单链表的常见操作,实例如下: #include<stdio.h> #include<stdlib.h> //定义单链表结构体 typedef int ElemType; typedef struct Node { ElemType data; struct Node *next; }LNode,*LinkList; //创建单链表 void Build(LinkList L) { int n; LinkList p,q; p=L; pr

  • 深入单链表的快速排序详解

    单链表的快排序和数组的快排序基本思想相同,同样是基于划分,但是又有很大的不同:单链表不支持基于下标的访问.故书中把待排序的链表拆分为2个子链表.为了简单起见,选择链表的第一个节点作为基准,然后进行比较,比基准小得节点放入左面的子链表,比基准大的放入右边的子链表.在对待排序链表扫描一遍之后,左边子链表的节点值都小于基准的值,右边子链表的值都大于基准的值,然后把基准插入到链表中,并作为连接两个子链表的桥梁.然后分别对左.右两个子链表进行递归快速排序,以提高性能.但是,由于单链表不能像数组那样随机存储

  • c语言实现单链表算法示例分享

    复制代码 代码如下: #include <stdio.h>#include <stdlib.h>typedef char DataType;typedef struct Node{    DataType data;    struct Node * Next;}ListNode,* LinkList;void Judement(LinkList head){ //判断分配内存    if (!head){        printf("Overflow.");

  • C语言实现单链表逆序与逆序输出实例

    单链表的逆序输出分为两种情况,一种是只逆序输出,实际上不逆序:另一种是把链表逆序.本文就分别实例讲述一下两种方法.具体如下: 1.逆序输出 实例代码如下: #include<iostream> #include<stack> #include<assert.h> using namespace std; typedef struct node{ int data; node * next; }node; //尾部添加 node * add(int n, node * h

  • 用C语言实现单链表的各种操作(一)

    最近,从新复习了一下数据结构中比较重要的几个部分,现在把自己的成果记录下来,主要就是仿照严蔚敏的<数据结构>(C 语言版),中的例子和后面的习题进行改编的.首先,是单链表的各种实现,其中,包含了一些常考的知识点.例如,单链表的逆置,单链表的合并,找到单链表的中间节点等的算法实现.下面这个是单链表的结构体的定义: 复制代码 代码如下: typedef struct LNode{ ElemType data; struct LNode *next;}LinkList; 下面的基本的单链表的操作:其

  • java实现单链表中是否有环的方法详解

    这是一道微软经典笔试题,就是两个指针h1,h2都从头开始遍历单链表,h1每次向前走1步,h2每次向前走2步,如果h2碰到了NULL,说明环不存在:如果h2碰到本应在身后的h1说明环存在(也就是发生了套圈). 如果环不存在,一定是h2先碰到NULL: 如果环存在,h2与h1一定会相遇,而且相遇的点在环内:h2比h1遍历的速度快,一定不会在开始的那段非环的链表部分相遇,所以当h1,h2都进入环后,h2每次移动都会使h2与h1之间在前进方向上的差距缩小1,最后,会使得h1和h2差距减少为0,也即相遇

  • php实现单链表的实例代码

    复制代码 代码如下: <?php //链表节点 class node {     public $id; //节点id     public $name; //节点名称     public $next; //下一节点 public function __construct($id, $name) {         $this->id = $id;         $this->name = $name;         $this->next = null;     } } /

  • C#定义并实现单链表实例解析

    本文以实例详细描述了C#定义并实现单链表的过程及原理.一般来说C#定义并实现单链表,代码包括构成链表的结点定义.用变量来实现表头.清空整个链表 .链表复位,使第一个结点成为当前结点.判断链表是否为空.判断当前结点是否为最后一个结点.返回当前结点的下一个结点的值,并使其成为当前结点.将当前结点移出链表,下一个结点成为当前结点等内容. 具体实现代码如下所示: using System; using System.IO; // 构成链表的结点定义 public class Node { public

  • C++中单链表的建立与基本操作

    准备数据 准备在链表操作中需要用到的变量及数据结构 示例代码如下: 复制代码 代码如下: struct Data   //数据结点类型 { string key;  //关键字  string name; int age;};struct CLType  //定义链表结构 { Data nodeData; Data *nextNode;}; 定义了链表数据元素的类型Data以及链表的数据结构CLType.结点的具体数据保存在一个结构Data中,而指针nextNode用来指向下一个结点. 我们可以

  • python单链表实现代码实例

    链表的定义:链表(linked list)是由一组被称为结点的数据元素组成的数据结构,每个结点都包含结点本身的信息和指向下一个结点的地址.由于每个结点都包含了可以链接起来的地址信息,所以用一个变量就能够访问整个结点序列.也就是说,结点包含两部分信息:一部分用于存储数据元素的值,称为信息域:另一部分用于存储下一个数据元素地址的指针,称为指针域.链表中的第一个结点的地址存储在一个单独的结点中,称为头结点或首结点.链表中的最后一个结点没有后继元素,其指针域为空. python单链表实现代码: 复制代码

  • 浅析C++中单链表的增、删、改、减

    首先是是一个简单的例子,单链表的建立和输出.程序1.1 复制代码 代码如下: #include<iostream>#include<string>using namespace std;struct Student{ string name; string score; Student *next;//定义了指向Candidate类型变量的指针};int main(){ int n;// cout<<"请输入学生的总数:"; cin>>n

随机推荐