(干货!)数据结构实验2-链表的实现和应用

(干货!)实验二 链表的实现和应用

1. 实验目的

掌握线性表的链式存储结构设计与基本操作的实现。

2.实验内容与要求

(1)定义线性表的链式存储表示;
(2)基于所设计的存储结构实现线性表的基本操作;
(3)线性表的应用:设线性表L1和L2分别代表集合A和B,试设计算法求A和B的并集C,并用线性表L3代表集合C;
(4)设计一个一元多项式计算器,要求能够:
①输入并建立多项式;
②输出多项式;
③执行两个多项式相加;

3.算法思路

(1)求并集:
①定义链表表L1、L2、L3
②基于所设计的存储结构实现链表的基本操作:初始化、输入输出、查找元素
③定义并集的函数,首先将L1全部复制进L3,再用LocateElem函数判断L3中是否含有L2中的元素,有则跳过,没有就新建结点将元素用尾插法插入L3表中。

(2)多项式求和
①初始化多项式,输入多项式内容
②进行加法运算:
③重复执行②直到ha或hb为空
④若ha非空则将其所指剩余链表加入结果链表;若hb非空则将其所指剩余链表加入结果链表。

⚠️在进行第②步时仍然需要分为两步:

步骤 内容✍️
1⃣️ 令ha->pa中第一个结点,hb->pb中的第一个结点,hc->链表中的最后一个结点
2⃣️ 比较ha和hb所指结点的指数:ha所指结点指数较小,将该结点插入结果链表,ha->下一结点,hc->新插入结点;hb所指结点指数较小,将该结点插入结果链表,hb->下一结点,hc->新插入结点;ha和hb所指结点指数相同,则将pb系数加到pa所指结点上:若两结点系数之和为0,两结点均销毁,ha、hb都指向下一结点;否则,ha所指结点插入结果链表,hb所指结点销毁,ha、hb均指向下一个结点。

4.上代码!

#include 
using namespace std;


typedef struct LNode
{
    int data;
    struct LNode *next;
}LNode,*LinkList;


typedef struct Node
{
    float coef;    //系数
    int expn;   //指数
    struct Node *next;
}Node,*polynomial;


void  InitList(LinkList &L)    //初始化链表
{
    L = (LinkList)malloc(sizeof(LNode));
    L->next = NULL;    //头结点
}



void Input(LinkList &L)     //尾插法
{
    LinkList end = L;
    int n;
    cout<<"请输入总数:"<<endl;
    cin>>n;
    cout<<"请输入数字:"<<endl;
    for(int i = n; i > 0; i--)
    {
        LinkList node;
        node = (LinkList)malloc(sizeof(LNode));
        cin>>node->data;
        end->next = node;
        end = node;
        end->next = NULL;
    }
}



void Output(LinkList L)
{
    LNode *p = L->next;
    while(p)
    {
        cout<<p->data<<" ";
        p = p->next;
    }
    cout<<endl;
}


int LocateElem(LinkList L,int e)   //判断L3中是否有L2元素 ,有返回1,没有返回0
{
    LinkList p = L->next;
    while(p)
    {
        if(p->data == e)
            return 1;
        else
            p = p->next;
    }
    return 0;
}



void Union(LinkList L1,LinkList L2,LinkList &L3)    //求L1、L2并集
{
    LinkList p,q,end_L3;
    p = L1->next;   //指向第一个结点
    q = L2->next;
    end_L3 = L3;    //L3尾指针
    while(p)   //把L1的值全部赋给L3
    {
        LinkList node;
        node = (LinkList)malloc(sizeof(LNode));
        node->data = p->data;
        end_L3->next = node;
        end_L3 = node;
        end_L3->next = NULL;
        p = p->next;
    }
    while (q)
    {
        if(!LocateElem(L3, q->data))    //判断L3中是否有L2元素
        {
            //没有则插入
            LinkList node;
            node = (LinkList)malloc(sizeof(LNode));
            node->data = q->data;
            end_L3->next = node;
            end_L3 = node;
            end_L3->next = NULL;
            q = q->next;
        }
        else
            q = q->next;
    }
}


//输入m项的系数和指数,建立表示一元多项式的带有头节点的有序链表P
//利用尾插法
void CreatePolyn(polynomial &P, int m)
{
    P = (polynomial)malloc(sizeof(Node));
    P->next = NULL;
    polynomial end = P;
 
    cout<<"请输入系数和指数(如5x^2输入(5 2)即可):"<<endl;
    for(int i = 0; i < m; i++)
    {
        polynomial node =(polynomial)malloc(sizeof(Node));
        cin>>node->coef>>node->expn;
        end->next = node;
        end = node;
        end->next = NULL;
    }
}



void AddPolyn(polynomial &pa,polynomial &pb)   //多项式求和
{
    polynomial ha = pa->next;
    polynomial hb = pb->next;
    polynomial hc = pa;
    while(ha&&hb)
    {
        if(ha->expn < hb->expn)     //ha的指数
        {
            hc->next = ha;
            ha = ha->next;
            hc = hc->next;
        }
        else if(ha->expn > hb->expn)   //hb可插入
        {
            hc->next = hb;
            hb = hb->next;
            hc = hc->next;
        }
        else
        {
            ha->coef = ha->coef + hb->coef;
            if(ha->coef)   //和不为0
            {
                hc->next = ha;
                ha = ha->next;
                hc = hc->next;
                hb = hb->next;
            }
            else
            {
                polynomial p = ha;
                ha = ha->next;
                free(p);
                p = hb;
                hb = hb->next;
                free(p);
            }
        }
    }
    if(!ha)
        hc->next = hb;
    if(!hb)
        hc->next = ha;
    free(pb);
}


void Print(polynomial P)
{
    polynomial p = P->next;
    if(p == NULL)   //多项式相加和为0时
    {
        cout<<0<<endl;
    }
    else
    {
        while (p->next)
        {
            if(p->expn == 0)
            {
                cout<<p->coef<<"+";
                p = p->next;
            }
            else if(p->expn == 1)
            {
                cout<<p->coef<<"x"<<"+";
                p = p->next;
            }
            else if(p->next->coef < 0)
            {
                cout<<p->coef<<"x^"<<p->expn;
                p = p->next;
            }
            else if(p->coef < 0)
            {
                cout<<-(p->coef)<<"x^"<<p->expn<<"-";
                p = p->next;
            }
            else
            {
                cout<<p->coef<<"x^"<<p->expn<<"+";
                p = p->next;
            }
        }
        cout<<p->coef<<"x^"<<p->expn<<endl;
    }
}



int main()
{
    cout<<"######链表求并集问题######"<<endl;
    LinkList L1,L2,L3;
    InitList(L1);
    InitList(L2);
    InitList(L3);
    Input(L1);
    Input(L2);
    Union(L1,L2,L3);
    cout<<"合并结果:"<<endl;
    Output(L3);
    cout<<endl;
    
    cout<<"######一元多项式求和问题######"<<endl;
    polynomial Pa,Pb;
    int m1,m2;
    cout<<"请分别输入多项式1和2的总项数:"<<endl;
    cin>>m1>>m2;
    CreatePolyn(Pa, m1);
    CreatePolyn(Pb, m2);
    cout<<"第一个一元多项式为:"<<endl;
    Print(Pa);
    cout<<"第二个一元多项式为:"<<endl;
    Print(Pb);
    cout<<"相加结果为:"<<endl;
    AddPolyn(Pa, Pb);
    Print(Pa);

}

5.运行结果

(干货!)数据结构实验2-链表的实现和应用_第1张图片
(干货!)数据结构实验2-链表的实现和应用_第2张图片

6.心得体会

第一次做题时忽略了并集有重复元素的情况,开始用了两种思路解决,第一个全部插入L3之后,遍历L3删除有重复元素的结点,但因为是无序排列,没有想出算法;第二种是通过查阅可以定义一维数组a,初始将其所有元素设为0,读到数x时,a[x]++,之后遍历时发现a[x]!=0说明是重复元素,需要删除。但这种方法占用存储空间太大,故舍去。最后使用了LocateElem函数,在插入前检查该L2元素是否已经存在在L3内。在做多项式时的输出需要考虑多种情况,指数和系数为1、0和负数时有着不同的输出方案。

帮助到你请点赞➕收藏➕关注哦~

你可能感兴趣的:(数据结构,链表,算法)