数据结构 线性表应用(C++)

1、线性表合并(A∪B、不要求顺序)

①求出A、B长度

②从LB中第1个数据元素开始,循环n次执行以下操作:
从LB中查找第i(1≤i≤n)个数据元素赋给e;
在LA中查找元素e,如果不存在,则将e插在表LA的最后。

void MergeList(List &LA, List LB)
{ // 将所有在线性表LB中但不在LA中的数据元素插入LA中
    m = ListLength(LA);
    n = ListLength(LB); // 求线性表的长度for(i=l;i<=n;i++)
    while (n--)
    {
        GetElem(LB, i, e);          // 取LB中第i个数据元素赋给e
        if (!LocateElem(LA, e))     // LA中不存在和e相同的数据元素
            ListInsert(LA, ++m, e); // 将e插在LA的最后
    }
}

   表长LA=m LB=n 循环执行n次

顺序表:取值与插入时间与表长无关,查找与表长m成正比,算法复杂度为O(mxn)

链表:取值时间与表长n成正比,插入与查找和表长m成正比,假设m大于n,算法复杂度为O(mxn)


(A∩B算法类似、元素输出的次序按在集合A中出现的次序)


void MergeList(LinkList &LA, LinkList LB)
{ // 将所有在线性表LA中但不在LB中的数据元素删除
    int m,n,e;
    m = ListLength(LA);
    n = ListLength(LB);
    int i = 1;
    while (m--)
    {
        GetElem(LA, i, e);      // 取LA中第i个数据元素赋给e
        if (!LocateElem(LB, e)) // LB中不存在和e相同的数据元素
            ListDelete(LA, i);  // 删除该元素
        else i++;
    }
}

2、有序表合并

1)顺序有序表合并

创建空表LC、比较LA、LB元素摘取到LC最后,直至LA、LB其中一表为空。对比剩余元素插入LC。

①创建一个表长为m+n的空表LC

②指针pc初始化指向LC第一个元素

③指针pa、pb初始化,分别指向LA、LB第一个元素

④当指针pa、pb未到表尾时依次比较二者所指向元素值,摘取元素值小的节点插入LC最后

⑤如果pb已到达LB表尾,依次将LA剩余元素插入LC最后

⑥如果pa已到达LA表尾,依次将LB剩余元素插入LC最后


void MergeList_Sq(SqList LA, SqList LB, SqList &LC)
{
    pa = LA.elem;
    pb = LB.elem;                      // 指针pa和pb的初值分别指向两个表的第一个元素
    LC.length = LA.length + LB.length; // 新表长度为待合并两表的长度之和
    LC.elem = new ElemType[LC.length]; // 为合并后的新表分配一个数组空间
    pc = LC.elem;                      // 指针pc指向新表的第一个元素
    pa_last = LA.elem + LA.length - 1; // 指针pa_last指向LA表的最后一个元素
    pb_last = LB.elem + LB.length - 1; // 指针pb_last指向LB表的最后一个元素
    while (pa <= pa_ last &&pb < = pb_ last)
    {
        // 两个表都非空
        if (*pa <= *pb)
            *pc++ = *pa++;
        // 依次“摘取”两表中值较小的结点
        else
            *pc++ = *pb++;
    }
    while (pa <= pa_ last)
        *pc++ = *pa++; // LB表已到达表尾, 将LA中剩余元素加入LC
    while (pb <= pb_ last)
        *pc + += *pb + +; // LA表已到达表尾,将LB中剩余元素加入LC
} // MergeList_ Sq

算法的时间复杂度是: O(ListLength(La)+ ListLength(Lb))
算法的空间复杂度是: O(ListLength(La) + ListLength(Lb))
*利用链表实现上述操作,不需要开辟新的存储空间,可以使空间复杂度降到最低

2)链式有序表合并

 ①指针pa、pb初始化,分别指向LA、LB第一个结点

②LC结点取值为LA头结点

③pc指针初始化指向LC头结点

④当指针pa、pb未到表尾时依次比较二者所指向元素值,摘取元素值小的节点插入LC最后

⑤将非空表剩余段插入pc所指结点后

⑥释放LB头结点

void MergeList_ L(LinkList &la, LinkList &Lb, LinkList &Lc)
{
    pa = La->next;
    pb = Lb->next;
    pc = Lc = La;
    // 用La的头结点作为Lc的头结点
    while (pa && pb)
    {
        if (pa->data < = pb->data)
        {
            pc->next = pa;
            pc = pa;
            pa = pa->next;
        }
        else
        {
            pc->next = pb;
            pc = pb;
            pb = pb->next;
        }
    }
    pc->next = pa ? pa : pb; // 插入剩余段
    delete Lb;
    // 释放Lb的头结点
}

算法的时间复杂度是: O(ListLength(La)+ ListLength(Lb))
算法的空间复杂度是: O(1)


3、多项式运算

利用数组p表示:数组中每个分量p[i]表示多项式每项的系数pi,数组分量的下标i即对应
项的指数。数组中非零的分量个数即多项式的项数。

两个多项式运算:

●创建一个新数组c
●分别从头遍历比较a和b的每一项
指数相同,对应系数相加,若其和不为零,则在c中增加一一个新项
指数不相同,则将指数较小的项复制到c中
●一个多项式已遍历完毕时,将另一一个剩余项依次复制到c中即可
*顺序存储结构存在问题:存储空间分配不灵活、运算的空间复杂度高


链式存储结构

typedef struct PNode
{
    float coef; // 系数
    int expn;// 指数
    struct PNode *next; // 指针域
} PNode, *Polynomial;


 


链表-多项式创建:

多项式的创建方法类似于链表的创建方法,区别在于多项式链表是一个有序表,每项的位置要经过比较才能确定。首先初始化一个空链表用来表示多项式,然后逐个输入各项,通过比较,找到第一个大于该输人项指数的项,将输人项插到此项的前面,这样即可保证多项式链表的有序性。

1、创建一个只有头节点的空链表。
2、根据多项式的项的个数n,循环n次执行以下操作:
①生成一个新节点*s;
②输入多项式当前项的系数和指数赋给新节点*s的数据域;
③设置一前驱指针pre,用于指向待找到的第一个大于输入项指数的节点的前驱,pre初始时指向头节点;
④指针q初始化,指向首元节点;
⑤循环向下逐个比较链表中当前节点中的值与输入项指数,找到第一个值大于输入项指数的节点*q;
⑥将输入项节点*s插入*q和其前驱节点pre之间。


void CreatePolyn(Polynomial &P, int n)
{
    // 输入m项的系数和指数,建立表示多项式的有序链表P
    P = new PNode;
    P->next = NULL;
    // 先建立一个带头结点的单链表
    for (i = 1; i <= n; ++i)
    {
        // 依次输入n个非零项
        s = new PNode;
        // 生成新结点
        cin >> s->coef >> s->expn;
        // 输入系数和指数
        pre = P;
        // pre用于保存q的前驱,初值为头结点
        q = P->next;
        // q初始化,指向首元结点
        while (q && q->expn < s->expn)
        {
            // 找到第一一个大于输入项指数的项*q
            pre = q;
            q = q->next;
            s->next = q; // 将输入项s插入到q和其前驱结点pre之间
            pre->next = s;
        }
    }
}

 时间复杂度:O(n^2)【循环输入n次*循环比较n次】


链表-多项式相加

①指针p1和p2初始化,分别指向Pa和Pb的首元结点。
②p3指向和多项式的当前结点,初值为Pa的头结点。
③当指针p1和p2均未到达相应表尾时,则循环比较p1和p2所指结点对应的指数值
(p1-> expn与p2->expn) 有下列3种情况:
当p1>expn= =p2-> expn时,则将两个结点中的系数相加
■若和不为零,则修改p1所指结点的系数值,同时删除p2所指结点
■若和为零,则删除p1和p2所指结点;
当p1->expn<p2-> expn时,则应摘取p1所指结点插入到和多项式"链表中去; 
当pTxexpn>p2-> expn时,则应摘取p2所指结点插入到“和多项式"链表中去。
④将非空多项式的剩余段插入到p3所指结点之后。
⑤释放Pb的头结点。 

void AddPolyn(Polynomial &Pa, Polynomial &Pb) // 多项式加法:Pa=Pa+Pb,利用两个多项式的节点构成“和多项式”
{
    p1 = Pa->next;
    p2 = Pb->next;   // p1和p2初始时分别指向Pa和Pb的首元节点
    p3 = Pa;         // p3指向和多项式的当前节点,初值为Pa
    while (p1 && p2) // p1和p2均非空
    {
        if (p1->expn == p2->expn)
        {                              // 指数相等
            sum = p1->coef + p2->coef; // sum保存两项的系数和
            if (sum != 0)              // 系数和不为0
            {
                // 修改Pa当前指向节点的系数值为两项系数的和
                p1->coef = sum;
                p3->next = p1;
                p3 = p1;       // 将修改后的Pa当前指向节点链接在p3之后,p3指向p1
                p1 = p1->next; // p1指向后一项
                r = p2;
                p2 = p2->next;
                delete r; // 删除Pb当前指向节点,p2指向后一项
            }
            else
            {
                r = p1;
                p1 = p1->next;
                delete r; // 删除Pa当前指向节点,p1指向后一项
                r = p2;
                p2 = p2->next;
                delete r; // 删除Pb当前指向节点,p2指向后一项
            }
        }
        else if (p1->expn < p2->expn) // Pa当前指向节点的指数值小
        {
            p3->next = p1; // 将p1链接在p3之后
            p3 = p1;       // p3指向p1
            p1 = p1->next; // p1指向后一项
        }

        else               // Pb当前指向节点的指数值小
        {                  // 将p2链接在p3之后
            p3->next = p2; // p3指向p2
            p3 = p2;       // p2指向后一项
            P2 = p2->next;
        }
    }                        // while
    p3->next = p1 ? p1 : p2; // 插人非空多项式的剩余段
    delete Pb;               // 释放Pb的头节点
}

图书信息管理系统存储结构

struct Book
{
    char id[20]; // ISBN
    char name[50]; // 书名
    int price;//定价
};

typedef struct
{ // 顺序表
    Book *elem;
    int length;
}  SqList;

typedef struct LNode
{ // 链表
    Book data;
    struct LNode *next;
} LNode, *LinkList;

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值