线性表基础&线性表应用:多项式

来源:互联网 发布:英语 加油 知乎 编辑:程序博客网 时间:2024/04/29 06:18

概念

  • 线性表(亦作顺序表)是最基本、最简单、也是最常用的一种数据结构。线性表中数据元素之间的关系是一对一的关系,即除了第一个和最后一个数据元素之外,其它数据元素都是首尾相接的。
  • 实际应用中,线性表都是以栈、对列、字符串等特殊线性表的形式中来使用的

结构特点

  • 有序性:集合中必存在唯一的一个“第一元素”;集合中必存在唯一的一个 “最后元素”;除最后一个元素之外,均有唯一的后继;除第一个元素之外,均有唯一的前驱
  • 均匀性:同一线性表中各数据元素必定具有相同的数据类型和长度
  • 数据元素的个数n定义为表的长度,n=0时成为空表。
  • 顺序存储结构和链式存储结构两种方法

基本操作

  • isEmpty(L),空表返回true,否则返回false
  • ClearList(L),将L置为空表
  • ListLength(L),返回L中元素个数
  • Get(L, i),返回L中第i个位置的元素
  • Prior(L, i),返回L中第i个位置的前驱元素
  • Next(L, i),返回L中第i个位置的后继元素
  • ListInsert(L, i, e),在L中第i个位置插入元素e
  • Delete(L, p),在L中删除位置p处的元素
  • Init(L),构造一个空的线性表
  • ListTraverse(L),遍历输出所有元素
  • ListLocate(L, x),值为x的元素在L中位置

实现方式

  • 连续存储空间,如数组,new ElemType[Len]等,可以随机读取下标位置的元素。但是删除和添加的时候复杂度是O(N)
  • 线性链表,也叫LinkList,每个元素的存储位置都要从头指针开始算起,用下标读取操作是O(N),删除和添加复杂度也是O(N)(因为需要从头指针开始找),合并两个有序链表的时候可以不开辟新的存储空间,直接修改各个元素的next指针即可
  • 静态链表,用数组描述的链表,需要预先分配一个较大的空间,但是在插入和删除操作的时候不需要移动元素。假设S为SLinkList变量,S[0].cur指示第一个节点在数组中的位置。有所不同的是需要自己实现分配(malloc或new)和回收(free或delete),插入的时候需要从备用链表上取得第一个节点作为待插入的新结点,反之,在删除时将从链表中删除下来的结点链接到备用链表上。
  • 循环链表,从表中任一结点出发均可找到表中其他结点。循环链表的操作和线性链表一致,不同在于遍历结束条件不是p->next为空,而是p->next等于头指针。
  • 双向链表,比单链表多了指向前一个元素的指针,使得PriorElem的执行时间也是O(1),单链表则是O(N)。

线性表应用:多项式

  • 用链表完成的存储多项式的一个应用,下面给出实现代码和测试结果
  • 头文件
#include <iostream>using namespace std;struct Node{    float coef;    int expn;    Node* next;    Node()    {        coef = 0;        expn = 0;        next = NULL;    }};class polynomial{public:    polynomial();    polynomial(polynomial &p);    ~polynomial();    void CreatePoly(int m);    void ClearPoly();    void PrintPoly();    void AddPoly(polynomial &p);    void SubtractPoly(polynomial &p);    void MultiplyPoly(polynomial &p);private:    Node* poly;    void ClearNode(Node* n);    void Insert(float coef, int expn);    void AddPoly(polynomial &p, float coefForMul, int expnForMul);};
  • cpp文件
#include "all.h"polynomial::polynomial(){    poly = NULL;}polynomial::polynomial(polynomial &p){    poly = NULL;    Node* cur = p.poly;    Node* copy = poly;    if (cur == NULL)        return;    else    {        copy = new Node;        copy->coef = cur->coef;        copy->expn = cur->expn;        poly = copy;    }    while (cur != NULL)    {        cur = cur->next;        if (cur != NULL)        {            copy->next = new Node;            copy->next->coef = cur->coef;            copy->next->expn = cur->expn;            copy = copy->next;        }    }}polynomial::~polynomial(){    ClearPoly();}void polynomial::CreatePoly(int m){    float coef;    int expn;    cout << "Please input coef & expn for " << m << " lines:" << endl;    for (int i = 0; i < m; i++)    {        cin >> coef >> expn;        //insert element        Insert(coef, expn);    }}//2 7 2 6 2 5 error void polynomial::Insert(float coef, int expn){    if (poly == NULL)    {        poly = new Node;        poly->coef = coef;        poly->expn = expn;    }    else    {        Node *cur = poly, *pre = poly;        //expn bigger than poly->expn        if (expn > poly->expn)        {            poly = new Node;            poly->coef = coef;            poly->expn = expn;            poly->next = cur;            return;        }        else if (expn == cur->expn)        {            poly->coef += coef;            return;        }        cur = cur->next;        //not insert before the first element        while (pre != NULL)        {            if (cur == NULL)            {                pre->next = new Node;                pre->next->coef = coef;                pre->next->expn = expn;                return;            }            else            {                if (cur->expn == expn)                {                    cur->coef += coef;                    return;                }                else if (cur->expn < expn)                {                    pre->next = new Node;                    pre->next->coef = coef;                    pre->next->expn = expn;                    pre->next->next = cur;                    return;                }                else                {                    pre = cur;                    cur = cur->next;                }            }        }    }}void polynomial::ClearPoly(){    ClearNode(poly);    poly = NULL;}void polynomial::ClearNode(Node* n){    if (n != NULL)    {        ClearNode(n->next);        delete n;    }}void polynomial::PrintPoly(){    bool isZero = true;    Node* cur = poly;    while (cur != NULL)    {        //print coef & expn        if (abs(cur->coef - 1) < 0.000001)        {            cout << "x^" << cur->expn;            isZero = false;        }        //not zero        else if (abs(cur->coef - 0) > 0.000001)        {            cout << cur->coef << "*x^" << cur->expn;            isZero = false;        }        //print op        if (cur->next != NULL)        {            if (cur->next->coef > 0 && abs(cur->coef - 0) > 0.000001)            {                cout << " + ";            }            else if (cur->next->coef < 0 && abs(cur->coef - 0) > 0.000001)            {                cout << " - ";            }            else            {                //if coef == 0, do not print                cur = cur->next;            }        }        cur = cur->next;    }    if (isZero)        cout << 0;    cout << endl;}//use for multiplyvoid polynomial::AddPoly(polynomial& p, float coefForMul, int expnForMul){    Node* cur = p.poly;    while (cur != NULL)    {        this->Insert(cur->coef * coefForMul, cur->expn + expnForMul);        cur = cur->next;    }}//addvoid polynomial::AddPoly(polynomial& p){    AddPoly(p, 1, 0);}//subvoid polynomial::SubtractPoly(polynomial& p){    Node* cur = p.poly;    while (cur != NULL)    {        this->Insert(-cur->coef, cur->expn);        cur = cur->next;    }}//mulvoid polynomial::MultiplyPoly(polynomial& p){    Node* cur = p.poly;    polynomial copy(*this);    //minus 1 * (this->poly)    p.Insert(-1, 0);    while (cur != NULL)    {        this->AddPoly(copy, cur->coef, cur->expn);        cur = cur->next;    }    p.Insert(1, 0);}
  • 主函数:
#include "all.h"/*test input1 11 31 21 31 11 2*/int main(){    polynomial p, p1;    p.CreatePoly(3);    p.PrintPoly();    p1.CreatePoly(3);    p1.PrintPoly();    polynomial p2(p);    cout << "p2:" << endl;    p2.PrintPoly();    p.AddPoly(p1);    cout << "after add:" << endl;    p.PrintPoly();    p.SubtractPoly(p1);    p.SubtractPoly(p1);    cout << "after sub:" << endl;    p.PrintPoly();    p.AddPoly(p1);    p.MultiplyPoly(p1);    cout << "after mul:" << endl;    p.PrintPoly();    system("pause");}
  • 结果
    效果图
    因为是随意写的代码,测试了一些基本的数据,可能存在某些bug。
0 1