什么是线性表

数据结构中最常用也最简单的应该就是线性表,它是一种线性结构(废话,不是线性结构怎么会叫线性表?当然不是废话,古人公孙龙就说白马非马,现代生物学家也说鲸鱼不是鱼)。

那什么是线性结构?

按数据逻辑结构来划分,数据结构就分为线性结构和非线性结构。

通俗来说就是排成一条线的结构,想象一下你去食堂排队打饭,前面站着一个人,后面也站着一个人,这样的结构就是线性结构。

线性表的定义

线性表就是线性结构的一种(其实其它像栈、队列什么的也可以说是一种特殊的线性表),先看一下线性表的定义:

零个或多个数据元素的有限序列。

零个或多个意味着线性表的数据元素n大于等于0,当n=0时,也就是空表。

有限意味着这个表的数据有限的,计算机中处理的数据都是有限的。

序列也就是说这一组元素是有顺序的,如果没有顺序乱成一团就不是排队而是打架了。



你去食堂打饭,发现来的时间点不对,一个人都没有,这时就是一张空表。于是你在外面转了一圈,回来一看,妈呀,一根烟的时间打饭窗口就站了几十号人,于是你赶快排在最后面,刚站好,你后面又一下站了十几个人。

这时,排在一个的就是第一个元素,排在最后一个的就是最后一个元素,排在你前面的就叫前驱,排你后面叫后继。而排在第一个的人前面已经没人了,所以第一个元素无前驱。同理,排在最后的一个无后继。

你排在中间实在太无聊了,于是数了一下,队伍总共100个人,也就是说线性表当前的长度为100。你又算了一下,从打饭窗口到门口可以排150个人,也就是说理论上队伍最多只能排150个人,150就是线性表的最大存储容量。如果还有人要排进来就要站到门外面了,就会发生数据溢出。

接口定义

后面我们将要介绍到多种实现线性表的方式,但不管哪种方式实现的线性表都是一样的,里面定义方法也是一样的。使用接口可以确保每种方式都实现了相同的操作,方便程序解耦,更利于其它模块调用以及编写单元测试。

下面给出定义的接口:

public interface ILinearList<T>
{
/// <summary>
/// 数组长度
/// </summary>
int Length
{
get;
} /// <summary>
/// 数组是否为空
/// </summary>
/// <returns></returns>
bool IsEmpty(); /// <summary>
///清空表
/// </summary>
void Clear(); /// <summary>
///通过索引获取数据元素
/// </summary>
/// <param name="index"></param>
/// <returns></returns>
T GetItem(int index); /// <summary>
/// 返回数据元素的索引
/// </summary>
/// <param name="t"></param>
/// <returns></returns>
int LocateItem(T t); /// <summary>
/// 将数据元素插入到指定位置
/// </summary>
/// <param name="item"></param>
/// <param name="index"></param>
void Insert(T item, int index); /// <summary>
/// 在数组末尾添加元素
/// </summary>
/// <param name="item"></param>
void Add(T item); /// <summary>
/// 删除指定索引的元素
/// </summary>
/// <param name="index"></param>
void Delete(int index);
}

线性表顺序存储结构

线性表有两种物理结构——顺序存储结构和链式存储结构。我们先来看看顺序存储结构。

顺序存储结构就和前面的排队一样,设计一个排队窗口,定下最多可以排多少人,然后按顺序一个个这么排下去。也就是说在内存中分配一块内存空间,然后把相同数据类型的数据元素依次存放下去。

如何实现

使用一维数组,把第一个数据元素存到数组下标为0的位置中,接着把线性表相邻的元素存储在数组中相邻的位置。

用C#实现,可以直接使用泛型数组。

初始化

首先我们先定义一些属性及字段:

    private T[] list;

    private int length = 0;

    public int MaxSize
{
private set;
get;
} public int Length
{
get { return length; }
}

构建线性表只需要给定数组最大容量(MaxSize)然后将list集合初始化就行了,这些我们可以直接放在构造函数里面:

    public SequentialList(int maxSize)
{
if (maxSize <= 0)
{
throw new Exception("the maxSize can not be less than zero");
}
MaxSize = maxSize;
list = new T[maxSize];
}

元素获取

元素的获取非常简单,直接通过下标返回就可以了:

    public T GetItem(int index)
{
return list[index];
}

添加元素

添加元素直接将数据元素放在数组的末尾(排队时新来一个人直接站在最后就好),并将length加1就行了:

    public void Add(T item)
{
if (isFull()) //判断数组是否已满
{
throw new Exception("This linear list is full");
}
length++;
list[length - 1] = item;
}

将元素插入至指定位置

打饭时,每新来一个人就直接排到队伍的最后面。但是现实却总是不那么美好,总有一些人会来插队。今天你去食堂去晚了,一看队伍已经站了差不多一百个人,所以机智的你看了下队伍的前列,在前面发现了坐在你边上的美女同事,于是赶快和她打个招呼以极其自然的方式插到了她的前面。你的插入对排在美女同事前面的人来说没有任何影响,他们的位置保持不变,但是排在她后面就要相应的全部向后移一个位置:

    public void Insert(T item, int index)
{
if (isFull())
{
throw new Exception("This linear list is full");
}
if (index < 0 || index > length)
{
throw new Exception("Location exception");
}
length++;
for (int i = length - 1; i > index; i--)
{
list[i] = list[i - 1];
}
list[index] = item;
}

删除

你正在排队打饭,突然发现肚子疼,心想总不能等下一边吃进去一边拉出来吧,于是赶快从队伍里退出来奔向洗手间,这个时候,排在你后面的人自然是满脸欢笑地目送你离开,他们所有人都可以往前面移一个位置:

    public void Delete(int index)
{
if (index < 0 || index > length - 1)
{
throw new Exception("Location exception");
}
length--;
for (int i = index; i < length; i++)
{
list[i] = list[i + 1];
}
}

完整代码如下(代码烂,轻拍):

/// <summary>
/// 线性表顺序结构
/// </summary>
public class SequentialList<T> : ILinearList<T>
{
private T[] list; private int length = 0; public int MaxSize
{
private set;
get;
} public int Length
{
get { return length; }
} public SequentialList(int maxSize)
{
if (maxSize <= 0)
{
throw new Exception("the maxSize can not be less than zero");
}
MaxSize = maxSize;
list = new T[maxSize];
} public bool IsEmpty()
{
return length == 0;
} public void Clear()
{
length = 0;
} public T GetItem(int index)
{
return list[index];
} public int LocateItem(T t)
{
for (int i = 0; i < list.Length; i++)
{
if (list[i].Equals(t))
{
return i;
}
}
return -1;
} public void Insert(T item, int index)
{
if (isFull())
{
throw new Exception("This linear list is full");
}
if (index < 0 || index > length)
{
throw new Exception("Location exception");
}
length++;
for (int i = length - 1; i > index; i--)
{
list[i] = list[i - 1];
}
list[index] = item;
} public void Add(T item)
{
if (isFull())
{
throw new Exception("This linear list is full");
}
length++;
list[length - 1] = item;
} public void Delete(int index)
{
if (index < 0 || index > length - 1)
{
throw new Exception("Location exception");
}
length--;
for (int i = index; i < length; i++)
{
list[i] = list[i + 1];
}
} bool isFull()
{
return length >= MaxSize;
}
}

C#实现数据结构——线性表(上)的更多相关文章

  1. [从今天开始修炼数据结构]线性表及其实现以及实现有Itertor的ArrayList和LinkedList

    一.线性表 1,什么是线性表 线性表就是零个或多个数据元素的有限序列.线性表中的每个元素只能有零个或一个前驱元素,零个或一个后继元素.在较复杂的线性表中,一个数据元素可以由若干个数据项组成.比如牵手排 ...

  2. [数据结构-线性表1.2] 链表与 LinkedList<T>(.NET 源码学习)

    [数据结构-线性表1.2] 链表与 LinkedList<T> [注:本篇文章源码内容较少,分析度较浅,请酌情选择阅读] 关键词:链表(数据结构)    C#中的链表(源码)    可空类 ...

  3. C# 数据结构 线性表(顺序表 链表 IList 数组)

    线性表 线性表是最简单.最基本.最常用的数据结构.数据元素 1 对 1的关系,这种关系是位置关系. 特点 (1)第一个元素和最后一个元素前后是没有数据元素,线性表中剩下的元素是近邻的,前后都有元素. ...

  4. C#实现数据结构——线性表(下)

    线性表链式存储结构 看了线性表的顺序存储,你肯定想线性表简是挺简单,但是我一开始怎么会知道有多少人排队?要分配多大的数组?而且插入和删除一个元素也太麻烦了,所有元素都要前移/后移,效率又低. 那怎么办 ...

  5. [置顶] ※数据结构※→☆线性表结构(queue)☆============循环队列 顺序存储结构(queue circular sequence)(十)

    循环队列 为充分利用向量空间,克服"假溢出"现象的方法是:将向量空间想象为一个首尾相接的圆环,并称这种向量为循环向量.存储在其中的队列称为循环队列(Circular Queue). ...

  6. [置顶] ※数据结构※→☆线性表结构(queue)☆============优先队列 链式存储结构(queue priority list)(十二)

    优先队列(priority queue) 普通的队列是一种先进先出的数据结构,元素在队列尾追加,而从队列头删除.在优先队列中,元素被赋予优先级.当访问元素时,具有最高优先级的元素最先删除.优先队列具有 ...

  7. 数据结构-线性表的链式存储相关算法(C语言实现)

    链表的简单介绍 为什么需要线性链表 当然是为了克服顺序表的缺点,在顺序表中,做插入和删除操作时,需要大量的移动元素,导致效率下降. 线性链表的分类 按照链接方式: 按照实现角度: 线性链表的创建和简单 ...

  8. 数据结构----线性表顺序和链式结构的使用(c)

    PS:在学习数据结构之前,我相信很多博友也都学习过一些语言,比如说java,c语言,c++,web等,我们之前用的一些方法大都是封装好的,就java而言,里面使用了大量的封装好的方法,一些算法也大都写 ...

  9. python数据结构——线性表

    线性表 线性表可以看作是一种线性结构(可以分为顺序线性结构,离散线性结构) 1. 线性表的种类: 顺序表 元素存储在一大块连续存储的地址中,首元素存入存储区的起始位置,其余元素顺序存放. (元素之间的 ...

随机推荐

  1. 今日推荐(三)AndroidResideMenu类似QQ侧滑效果

    效果图: DEMO 本代码即是DEMO,您可以下载后选择您喜欢的IDE运行.SDK版本建议使用4.0以上 Version Migration 从 v1.0, v1.1, v1.2, v1.3 升级到  ...

  2. 通过GitHub Pages建立个人站点(详细步骤)

    1 Git简介 2 为什么使用Github Pages 3 创建Github Pages 3.1 安装git工具. 3.2 两种pages模式 3.3 创建步骤 3.4 常用命令 4 使用Jekyll ...

  3. Android(java)学习笔记220:开发一个多界面的应用程序之界面间数据传递

    1.界面跳转的数据传递 (1)intent.setData() --> intent.getData():     传递的数据比较简单,一般是文本类型的数据String:倘若我们传递的数据比较复 ...

  4. IDL绘制黑体辐射曲线

    普朗克定律是热红外遥感中常常使用的三大定律之一,描述了黑体辐射能量的情况.绝对黑体的辐射光谱对于研究一切物体的辐射规律具有根本的意义.1900年普朗克引进量子概念,将辐射当做不连续的量子发射,成功地从 ...

  5. java.util 中的property

    学习中 两个博客: http://swiftlet.net/archives/1023 http://www.cnblogs.com/lingiu/p/3468464.html

  6. win7/win8 64位系统注册TeeChart8.ocx 控件---以及dllregisterserver调用失败问题解决办法

    TeeChart控件就不多介绍了,很多朋友不知道开始怎么注册使用,尤其是在64位系统下如何注册的问题,具体如下: win7.win8  64位系统问题所在: 64位的系统一般都是可以安装32位程序的 ...

  7. win10的独立存储

    win10的独立存储和win8的大致相同 Windows.Storage.ApplicationDataContainer roamingSettings = Windows.Storage.Appl ...

  8. jquery获取value值

    $(function(){ alert(1); var a=$("#a004").val(); var a1=$("#b004").val(); //.val就 ...

  9. 原创 HTML5:JS操作SVG实践体会

    在工业信息化系统里,常常需要动态呈现系统的数据在一张示意图里,用于展现系统状态,分析结果等.这样用JavaScript操作svg 元素就有现实意义.本人近期做了一些实践,现分享一下. 需求: 你下面这 ...

  10. z-index的理解 z-index 属性仅在节点的 position 属性为 relative, absolute 或者 fixed 时生效.

    今天做游戏的Exercise模式的时候,发现把所有的div设置为position:absolute;后,点击play进入到游戏界面的时候,鼠标点击数字的时候,完全没反应.经过我的反复检查,发现只要给所 ...