六、线性表的应用/案例分析和实现

本文涉及的产品
传统型负载均衡 CLB,每月750个小时 15LCU
网络型负载均衡 NLB,每月750个小时 15LCU
应用型负载均衡 ALB,每月750个小时 15LCU
简介: 六、线性表的应用/案例分析和实现

1、线性表的两个应用


1.1 线性表的合并


将两个无序的线性表La和Lb合并成一个新的线性表,要求新的线性表中不能出现重复的元素。

La = {7,5,3,11};
Lb = {2,6,3};


算法步骤和伪代码如下所示:

依次取出Lb中的每个元素,执行下述操作:
  1、在La中查找该元素
  2、若元素在La中找不到,则将其插入到La的最后
void union(List &La, List &Lb)
{
  LaLen = GetLength(La);  //获取链表La的长度
  LbLen = GetLength(Lb);  //获取链表Lb的长度
  for(int i = 0; i < LbLen; ++i)
  {
    Elem tVal = GetElem(Lb, i);   //获取Lb索引为i的元素Elem
    if(!LocateElem(La, tVal))   //检查tVal是否已经存在于La中
      ListInsert(La, tVal);   //若不重复,则插入到La的尾部
  }
}


算法的时间复杂度为: O(LaLen∗LbLen)



1.2 有序表的合并


将两个数据元素已经排好序的非递减有序线性表La和Lb合并为一个新的线性表,新的线性表中的元素不能有重复且数据元素仍按照非递减的顺序排列。

La = {1,7,8};
Lb = {2,4,6,8,10,11};


算法步骤和伪代码如下所示:

1、首先创建一个空表Lc
  2、依次从La或者Lb中“摘取”元素值较小的结点插入到Lc表的最后,直至其中一个表变成空表为      
  止。
  3、将La和Lb中的非空表剩余结点插入到Lc表的最后。




1.2.1 用顺序表实现有序表合并

c2094e51ce124a119cbea244295fcb9c.png

void MergeList(List &La, List &Lb, list &Lc)
{//双指针法合并有序顺序链表,同时去重
  int pa = 0, pb = 0;   //指向La和Lb表的第一个元素的两个指针
  int pc = 0;       //指向新表Lc的第一个元素的指针
  Lc.length = La.length + Lb.length;  //获得新表的最大长度
  Lc.elem = new ElemType[Lc.length];  //为新表分配新的数组空间
  while(pa < La.length && pb < Lb.length)
  { 
    if(La[pa] < Lb[pb])       //当前La表中的元素更小
      Lc[pc++] = La[pa++];
    else if(La[pa] == Lb[pb])   //当前La表中的元素和Lb表中的元素同样大小
    {
      Lc[pc++] = La[pa++];
      ++pb;
    }
    else              //当前Lb表中的元素更小
      Lc[pc++] = Lb[pb++];
  }
  while(pa < La.length) Lc[pc++] = La[pa++];//插入La表剩余的元素
  while(pb < Lb.length) Lc[pc++] = Lb[pb++];//插入Lb表剩余的元素
}

算法的时间复杂度为:O(La.length+Lb.length)


算法的空间复杂度为:O(La.length+Lb.length)


1.2.2 用链表实现有序表的合并

1ff735e88ace43b49f9dc04832e88f1c.png

void MergeList(List &La, List &Lb, List &Lc)
{//双指针法合并两个有序链表,添加去重,默认原链表中没有重复元素
  list *pa = La->next, *pb = Lb->next;  //记录链表La和Lb的首元结点的位置
  pc = Lc = La;             //将La的头结点作为Lc的头结点
  while(pa && pb)
  {
    if(pa->data < pb->data)
    {
      pc->next = pa;
      pc = pa;
      pa = pa->next;
    }
    else if(pa->date==pb->data)
    {
      pc->next = pa;
      pc = pa;
      pa = pa->next;
      list *t = pb;
      pb= pb->next;
      delete t;
    }
    else
    {
      pc->next = pb;
      pc = pb;
      pb = pb->next;
    }
  }
  pc->next = pa?pa:pb;
  delete Lb;
}

算法的时间复杂度为:O(La.length+Lb.length)


算法的空间复杂度为:  O(1)




2、案例分析与实现


2.1 图书管理系统


线性表中每一个数据元素都是一个复杂的结构类型,可以用类或者结构体来定义,类中的成员项包括图书编号,书名,价格,存档日期,是否可以借阅等等。


图书管理系统的实现可以用顺序表来实现,

f4f24d637497433993057f5d53bba954.png

也可以用链表来实现:

ff6b4b3c4c1e413d843d225f2425888f.png


当系统中的图书的数量变化不大,同时不需要频繁对图书进行插入或者删除操作,但需要快速查找某个或者某些图书的信息,则使用线性表实现更好;若需要进行频繁的插入和删除操作,则使用链式存储结构更加合理。


系统的结构类型和和表的类型定义示例如下所示:

struct Book
{
  char id[20];    //ISBN
  char name[50];    //name
  int price;      //定价
};
/*顺序表定义*/
class SqList
{
  Book *elem;
  int length;
};
/*链表定义*/
class LNode
{
  Book data;
  LNode *next;
};



相关实践学习
SLB负载均衡实践
本场景通过使用阿里云负载均衡 SLB 以及对负载均衡 SLB 后端服务器 ECS 的权重进行修改,快速解决服务器响应速度慢的问题
负载均衡入门与产品使用指南
负载均衡(Server Load Balancer)是对多台云服务器进行流量分发的负载均衡服务,可以通过流量分发扩展应用系统对外的服务能力,通过消除单点故障提升应用系统的可用性。 本课程主要介绍负载均衡的相关技术以及阿里云负载均衡产品的使用方法。
相关文章
|
3月前
|
存储 编译器 C++
【初阶数据结构】掌握二叉树遍历技巧与信息求解:深入解析四种遍历方法及树的结构与统计分析
【初阶数据结构】掌握二叉树遍历技巧与信息求解:深入解析四种遍历方法及树的结构与统计分析
|
7月前
|
存储 算法
数据结构和算法学习记录——设计循环队列(数组实现循环队列)核心思路、题解过程、完整题解
数据结构和算法学习记录——设计循环队列(数组实现循环队列)核心思路、题解过程、完整题解
55 1
|
8月前
|
人工智能 算法 C语言
【408数据结构与算法】—线性表的定义和分析(二)
【408数据结构与算法】—线性表的定义和分析(二)
|
前端开发
前端学习案例30-二叉搜索树删除操作分析
前端学习案例30-二叉搜索树删除操作分析
72 0
前端学习案例30-二叉搜索树删除操作分析
|
算法 Go 开发者
二分查找的思路分析|学习笔记
快速学习二分查找的思路分析
二分查找的思路分析|学习笔记
数据结构学习笔记:顺序表的删除操作及其演化题目总结
数据结构学习笔记:顺序表的删除操作及其演化题目总结
数据结构学习笔记:顺序表的删除操作及其演化题目总结
|
存储 算法 C++
算法设计与分析 链表
算法设计与分析 链表
110 0
算法设计与分析 链表
|
存储 算法 Perl
【数据结构与算法】第四章:链表拓展与线性表总结
前面介绍了线性表的顺序表和链表,本章讲对链表应用拓展,具体介绍单链表、循环链表、双向链表等,并将顺序表与链表进行比较,更直观的感受两种不同结构的差异所在以及各自的优势短板,最后对线性表进行总结。
190 0
【数据结构与算法】第四章:链表拓展与线性表总结
|
存储 算法 NoSQL
数据结构与算法分析(三) 线性表
数据结构与算法分析(三) 线性表
数据结构与算法分析(三) 线性表