1、线性表

  概念::零个或多个数据元素的有序序列。

  描述:

2、线性表的抽象数据类型:

  ADT线性表

  Data:线性表的数据对象集合为{a1,a2,...,an},每个元素的类型均为DataType。其中除第一个元素a1外,每一个元素有且只有一个直接前驱元素,除了最后一个元素an外,每一个元素有且只有一个直接后继元素,数据元素之间的关系是一对一的关系。

  Operation

  Init(*L):初始化操作,建立一个空的线性表;

  IsEmpty(*L):判断线性表是否为空,若为空,则返回true,否则返回false;

  Clear(*L):清空线性表;

  GetElem(*L,i):返回线性表位置为i的元素;

  LocateElem(*L,e):返回线性表中与元素i相同值的位置;

  Insert(*L,i,e):在线性表i位置插入元素e;

  Delete(*L,i):删除线性表位置i的元素;

  GetLength(*L):获得当前线性表的长度。

endADT

3、线性表的顺序存储结构

  概念:用一段地址连续的存储单元存储线性表的数据元素。

  如图:

    

    算法的C#语言实现

    

  /// <summary>
/// 线性表的顺序存储结构
/// </summary>
public class SequentialStorageLinearList<T>
{
//最大存放数量
private int _maxLength; /// <summary>
/// 最大存储数量
/// </summary>
public int MaxLength
{
get
{
return _maxLength;
}
} // 当前存放位置
private int _currentLength; private T[] _LinearList; //利用构造函数创建一个数组,用来存放数据
public SequentialStorageLinearList(int maxLength)
{
if (maxLength <= 0)
throw new Exception("The length can not be less than zero.");
_maxLength = maxLength;
_currentLength = 0;
_LinearList = new T[_maxLength];
} /// <summary>
/// 判断线性表是否为空
/// </summary>
/// <returns></returns>
public bool IsEmpty()
{
return _currentLength == 0;
} /// <summary>
/// 清空所有的元素
/// </summary>
public void ClearAll()
{
if (_currentLength > 0)
{
/*
* 在高级语言.net中,我们可以重新创建一个新的数组,将其指向当前的_linearList
*由于是托管代码,资源不需要手动释放,会自动释放
*但是在c语言中,我们需要手动的释放其占用的空间(free)
*/
_LinearList = new T[0];
}
} /// <summary>
/// 根据
/// </summary>
/// <param name="i"></param>
/// <returns></returns>
public T GetElement(int i)
{
if (_currentLength == 0 || _currentLength < i || i < 1)
throw new Exception("Not find any Element.");
T t = _LinearList[i];
return t;
} /// <summary>
/// 查找数据中是否存在元素e
/// </summary>
/// <param name="e"></param>
/// <returns></returns>
public int IndexOf(T e)
{
if (_currentLength == 0)
throw new Exception("The array is empty.");
for (int i = 0; i < _currentLength; i++)
{
T t = _LinearList[i];
/*
* T可能是引用类型,我们暂时的比较方式,不考虑重写equals
*/
if (t.Equals(e))
{
return i;
}
}
return -1;
} /// <summary>
/// 在位置i处插入元素e
/// </summary>
/// <param name="e">待插入的元素e</param>
/// <param name="i">插入位置i</param>
public void Insert(T e, int i)
{
//数组已经存满
if (_currentLength == _maxLength)
throw new Exception("The array is full.");
//当i位置不在范围内
if (i < 1 || i > _currentLength + 1)
throw new Exception("The location is illegal.");
//若插入的数据不在表尾,在需要移动插入位置后面的数据一位
if (i <= _currentLength - 1)
{
for (int j = _currentLength - 1; j > i; j--)
{
_LinearList[j + 1] = _LinearList[j];
}
}
_LinearList[i - 1] = e;
_currentLength++;
} /// <summary>
/// 删除位置i处的元素
/// </summary>
/// <param name="i">位置i</param>
public void Delete(int i)
{
if (_currentLength == 0)
throw new Exception("The array is Empty.");
if (i < 1 || i > _currentLength)
throw new Exception("The location is illegal.");
//删除位置i元素后需要将i后面的元素依次递增一位
if (i < _currentLength)
{
for (int k = k-1; k < _currentLength; k++)
{
_LinearList[k - 1] = _LinearList[k];
}
}
_currentLength--;
}
}

4、线性表的链式存储结构

  数据域:存储数据元素信息的域;

  指针域:存储直接后继位置的域;

  节点(Node):由数据域和指针域组成的数据元素ai的存储映像;

  我们把由n个节点链结成一个链表,即为线性表的链式存储结构。

  如图:

    

5、单链表

  链表的每个将结点中只包含一个指针域,我们称为单链表。同时我们把链表中第  一个结点的存储位置称为头指针。同时在链表的第一个结点前附设一个结点,称  为头结点。

  单链表的C#实现:

  

 /// <summary>
/// 单链表的实现
/// </summary>
/// <typeparam name="T"></typeparam>
public class SingleNode<T>
{
/// <summary>
/// 序号
/// </summary>
public int Index { get; private set; } /// <summary>
/// 头指针
/// </summary>
public SingleNode<T> HeadNode { get; private set; } /// <summary>
/// 指针域
/// </summary>
public SingleNode<T> NextNode { get; set; } /// <summary>
/// 数据域
/// </summary>
public T Data { get; set; } public SingleNode()
{
HeadNode = new SingleNode<T>();
Index = ;
NextNode = null;
} public SingleNode(T t)
{
Data = t;
NextNode = null;
} /// <summary>
/// 判断单链表是否为空
/// </summary>
/// <returns></returns>
public bool IsEmpty()
{
return Index == ;
} /// <summary>
/// 清空所有的元素
/// </summary>
public void ClearAll()
{
if (Index > )
{
NextNode = null;
Data = default(T);
Index = ;
}
} /// <summary>
/// 获得位置为i的元素
/// </summary>
/// <param name="i"></param>
/// <returns></returns>
public SingleNode<T> GetElement(int i)
{
if (Index == || Index < i || i < )
throw new Exception("Not find any Element.");
SingleNode<T> head = HeadNode;
SingleNode<T> next;
for (int k = ; k < Index; k++)
{
next = head.NextNode;
if (next.Index == i)
{
return next;
}
head = next.NextNode;
}
return null;
} /// <summary>
/// 查找数据中是否存在元素e
/// </summary>
/// <param name="e"></param>
/// <returns></returns>
public int IndexOf(T e)
{
if (Index == )
throw new Exception("The array is empty.");
SingleNode<T> head = HeadNode;
SingleNode<T> next;
for (int k = ; k < Index; k++)
{
next = head.NextNode;
if (next.Equals(e))
{
return next.Index;
}
head = next.NextNode;
}
return -;
} /// <summary>
/// 在位置i处插入元素e
/// </summary>
/// <param name="e">待插入的元素e</param>
/// <param name="i">插入位置i</param>
public void Insert(T t, int i)
{
/*
*1.先判断i是否存在
*2.若存在则创建一个空节点,将值t赋给该空节点
*3.修改该节点的前驱和后继节点
*/
if (i < || i > Index)
throw new Exception("The location is illegal.");
//获得当前位置i的节点
var preNode = GetElement(i); //创建空节点
SingleNode<T> currentNode = new SingleNode<T>(t); //修改前驱节点指向当前节点
var nextNode = preNode.NextNode;
preNode.NextNode = currentNode; //将新节点的后继节点修改
currentNode.NextNode = nextNode; Index++;
} /// <summary>
/// 删除位置i处的元素
/// </summary>
/// <param name="i">位置i</param>
public void Delete(int i)
{
/*
*1.查找位置为i的节点
*2.修改节点的前继节点为查找节点的下一节点
*/
//获得当前位置i-1的节点
if (i < || i > Index)
throw new Exception("The location is illegal.");
var preNode = GetElement(i - );
var nextNextNode = preNode.NextNode.NextNode;
preNode.NextNode = nextNextNode;
Index--;
}
}
 

6、循环链表

  将单链表中终端节点的指针端由空指针改为指向头节点,这样整个单链表就成为了一个环,这种头尾相接的单链表称为单循环链表。

  如图:

    

  实现代码类似与单链表。

7、双向链表

  在单链表的每个节点中,再设置一个指向其前驱节点的指针,从而形成的链表,我们称为双向链表。

  如图:

    

  C#代码实现:

  

8、链表和线性表的优缺点比较

    如图:

      

9、参考资料:

   单链表的19种操作: http://www.cnblogs.com/lifuqing/archive/2011/08/20/List.html

    单链表的C#实现:http://www.cnblogs.com/linzheng/news/2011/07/14/2106173.html

第三章 线性表(C#实现)的更多相关文章

  1. 《数据结构与算法分析:C语言描述》复习——第三章“线性表、栈和队列”——双向链表

    2014.06.14 20:17 简介: 双向链表是LRU Cache中要用到的基本结构,每个链表节点左右分别指向上一个和下一个节点,能够自由地左右遍历. 图示: 实现: // My implemen ...

  2. HTML第三章:表单

    第三章:表单 表单标签form:<form></form>//相当于一张记录用户信息的单子    常用属性:method:表单的提交方式,常用的值有两个             ...

  3. 数据结构(c语言版,严蔚敏)第2章线性表

    弟2章线性表

  4. [数据结构 - 第3章] 线性表之双向链表(C语言实现)

    一.什么是双向链表? 双向链表(double linked list)是在单链表的每个结点中,再设置一个指向其前驱结点的指针域.所以在双向链表中的结点都有两个指针域,一个指向直接后继,另一个指向直接前 ...

  5. 《SQL CookBook 》笔记-第三章-多表查询

    目录 3.1 叠加两个行集 3.2 合并相关行 3.3 查找两个表中相同的行 3.4 查找只存在于一个表中的数据 3.5 从一个表检索与另一个表不相关的行 3.6 新增连接查询而不影响其他连接查询 3 ...

  6. [数据结构 - 第3章] 线性表之单链表(C++实现)

    一.类定义 单链表类的定义如下: #ifndef SIGNALLIST_H #define SIGNALLIST_H typedef int ElemType; /* "ElemType类型 ...

  7. 第2章 线性表《C#数据结构和算法》

    ( )除第一个位置的数据 元素外,其它数据元素位置的前面都只有一个数据元素:( )除最后一个位置的 数据元素外,其它数据元素位置的后面都只有一个元素.也就是说,数据元素是 一个接一个的排列.因此,可以 ...

  8. 数据结构(C语言版)-第2章 线性表

    #define MAXSIZE 100 //最大长度 typedef struct { ElemType *elem; //指向数据元素的基地址 int length; //线性表的当前长度 }SqL ...

  9. 《数据结构与STL-第二章 线性表》读书笔记

    线性表 定义 线性表(linear list)是由零个或多个相同类型的数据元素构成的有限序列. 存储结构 顺序存储 最简单的存储方法是顺序存储法,即把线性表的数据元素按照逻辑次序顺序地放在一组地址连续 ...

随机推荐

  1. ORACLE case when then

    Oracle CASE WHEN 用法介绍 1. CASE WHEN 表达式有两种形式 --简单Case函数 CASE sex WHEN '1' THEN '男' WHEN '2' THEN '女' ...

  2. LINQ中的Aggregate用法总结

    Aggregate这个语法可以做一些复杂的聚合运算,例如累计求和,累计求乘积.它接受2个参数,一般第一个参数是称为累积数(默认情况下等于第一个值),而第二个代表了下一个值.第一次计算之后,计算的结果会 ...

  3. MQ学习(二)----ActiveMQ简介(转)

    1.  什么是ActiveMQ ActiveMQ是一种开源的,实现了JMS1.1规范的,面向消息(MOM)的中间件,为应用程序提供高效的.可扩展的.稳定的和安全的企业级消息通信.ActiveMQ使用A ...

  4. springmvc入门demo

    目录结构: package com.wyl; import org.springframework.stereotype.Controller; import org.springframework. ...

  5. 基于jQuery带标题的图片3D切换焦点图

    今天给大家分享一款基于jQuery带标题的图片3D切换焦点图.这款焦点图适用浏览器:IE8.360.FireFox.Chrome.Safari.Opera.傲游.搜狗.世界之窗. 实现的代码. htm ...

  6. 通过class类来实例化其他类的对象(使用有参构造函数)

    import java.lang.reflect.Constructor; import java.lang.reflect.InvocationTargetException; class Pers ...

  7. 什么是LED锡膏?

    LED锡膏熔点172℃,俗称中温锡膏,其合金为Sn64Bi35Ag1,此类产品是含Bi类的低熔点无铅锡膏,加入Ag改变了SnBi合金的焊点的机械强度.大幅度提高焊点可靠性,适用于高频调谐器系列产品的贴 ...

  8. GitHub Android 最火开源项目Top20 GitHub 上的开源项目不胜枚举,越来越多的开源项目正在迁移到GitHub平台上。基于不要重复造轮子的原则,了解当下比较流行的Android与iOS开源项目很是必要。利用这些项目,有时能够让你达到事半功倍的效果。

    1. ActionBarSherlock(推荐) ActionBarSherlock应该算得上是GitHub上最火的Android开源项目了,它是一个独立的库,通过一个API和主题,开发者就可以很方便 ...

  9. swith 语句详解

    switch 语句的格式: switch ( 整型或字符型变量 ) { case 变量可能值1 :   分支一; break; case 变量可能值2 :   分支二; break; case 变量可 ...

  10. 那些年我们写过的三重循环----CodeForces 295B Greg and Graph 重温Floyd算法

    Greg and Graph time limit per test 3 seconds memory limit per test 256 megabytes input standard inpu ...