什么是线性表

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

那什么是线性结构?

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

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

线性表的定义

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

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

零个或多个意味着线性表的数据元素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. 《Android开发艺术探索》读书笔记 (10) 第10章 Android的消息机制

    第10章 Android的消息机制 10.1 Android消息机制概述 (1)Android的消息机制主要是指Handler的运行机制,其底层需要MessageQueue和Looper的支撑.Mes ...

  2. 对话框 自定义 IOS风格 包青天

    activity     private void showDialog1() {         message = "您输入的邮箱后缀不是公司邮箱地址\n将导致您的借款审核不通过,请重新 ...

  3. FileWriter类的flush方法的作用

    FileWriter类的flush方法的作用 每次io都会影响性能,将需要写入的内容,放入缓冲区中,然后调用flush方法,将缓冲区内容写入文件中.

  4. C# WebService 基础实例

    1.整个Demo结构:如下图: 2.新建项目--选择asp.net web服务应用程序TestWebService 3.重新命名Service1.asmx为MyService.asmx 4.右键MyS ...

  5. CSS 布局Float 【4】

    一些浮动模型的基本知识:浮动模型也是一种可视化格式模型,浮动的框可以左右移动(根据float属性值而定),直到它的外边缘碰到包含框 或者另一个浮动元素的框的边缘.浮动元素不在文档的普通流中,文档的普通 ...

  6. asp.net 图片质量压缩(不改变尺寸)

    private static ImageCodecInfo GetEncoderInfo(String mimeType) { int j; ImageCodecInfo[] encoders; en ...

  7. 【USACO 1.5.3】特殊的质数肋骨

    [题目描述]农民约翰的母牛总是生产出最好的肋骨.你能通过农民约翰和美国农业部标记在每根肋骨上的数字认出它们. 农民约翰确定他卖给买方的是真正的质数肋骨,是因为从右边开始切下肋骨,每次还剩下的肋骨上的数 ...

  8. Java简介(4)-关键字

    abstract assert boolean break byte byte case catch char class const continue default do-while double ...

  9. underscorejs-where学习

    2.7 where 2.7.1 语法: _.where(list, predicate) 2.7.2 说明: 对list集合的每个对象依次与predicate对象进行匹配,返回一个数组(数组为匹配成功 ...

  10. Apache Commons DbUtils Problem