.NET Core 数据结构与算法 1-1

本节内容为顺序表

简介

线性表是简单、基本、常用的数据结构。线性表是线性结构的抽象 (Abstract),线性结构的特点是结构中的数据元素之间存在一对一的线性关系。这 种一对一的关系指的是数据元素之间的位置关系,即:

  • 除第一个位置的数据元素外,其它数据元素位置的前面都只有一个数据元素;
  • 除后一个位置的数据元素外,其它数据元素位置的后面都只有一个元素。也就是说,数据元素是 一个接一个的排列。因此,可以把线性表想象为一种数据元素序列的数据结构。

本节我们对线性表中的顺序表进行一个讲解。

保存线性表简单、自然的方式,就是把表中的元素一个接一个地放进顺序的存储单元,这就是线性表的顺序存储(Sequence Storage)。线性表的顺序存储是指在内存中用一块地址连续的空间依次存放线性表的数据元素, 用这种方式存储的线性表叫顺序表(Sequence List)。说的明确一些也就是说,顺序表就是我们所接触过的数组。

线性表接口IListDS<T>

我们首先对我们会涉及到的函数进行一次封装,打包进线性表的接口中

interface IListDS<T>
{
int GetLength();//求长度,我们也可以通过属性进行操作
void Clear();//清空操作
bool IsEmpty();//判断线性表是否为空
void Append(T item);//向后追加操作
void Insert(T item, int i);//插入操作
T Delete(int i);//删除操作
T GetElem(int i);//取表元
}

对于C语言,我们很多需要使用函数进行操作,但是在C#中,我们有索引器,属性等一系列语法糖,因此我们在后面操作的时候会把这些都展示给你们看。

事实上在我们之前的C#初级教程中的综合练习,就是关于我们的线性表操作,你可以返回去参考你的代码。

顺序表类SeqList<T>

为了方便起见,我们在此处不做可变长度的线性表,如果需要使用可变长度,这里有那么一种思路供读者思考:定义一个字段为容量(Cap),一个为长度(len),长度是以及存储的空间大小,容量是总空间,如果长度和容量相等的时候,证明我们的表已经满了,那么就向后追加空的数组即可。

不过在这里我们不讨论这种,我们仅仅使用定长的就足够展示了

class SeqList<T>:IListDS<T>
{
private int length;//长度
private int size;
private int lastIndex;//最后一个元素的索引
private T[] data;
public int Length{get{return lastIndex+1;}}
//初始化
public SeqList<T>(int size)
{
this.data = new T[size];
this.lastIndex = -1;
this.size = size;
}
//清除内部元素
public void Clear()
{
this.data = new T[this.size];
lastIndex = -1;
}
//判断是否为空,只需要判断最后一个元素的索引是否为-1即可
public bool IsEmpty()
{
return lastIndex==-1?true:false;
}
//获取长度
public int GetLength()
{
return lastIndex + 1;
}
//是否已满
public bool IsFull()
{
return size == lastIndex+1?true:false;
}
//向后追加
public void Append(T item)
{
//只需要判断是否已满即可
if(!IsFull())
{
data[lastIndex++] = item;
}
else
{
Console.WriteLine("It is Full");
}
}
//在指定位置插入,index指代位置而不是索引
public void Insert(T item,int index)
{
//首先判断是否已满
if(IsFull())
{
Console.WriteLine("It is Full");
return;
}
if(index<1||index>lastIndex+2)
{
Console.WriteLine("error");
return;
}
//最后一位插入
if (i == last +2)
{
data[i-1] = item;
}
else
{
//元素移动
for (int j = lastIndex; j>= i-1; --j)
{
data[j + 1] = data[j];
}
data[i-1] = item;
}
lastIndex++;
}
public T Delete(int i)
{
T tmp = default(T); //判断表是否为空
if (IsEmpty())
{
Console.WriteLine("List is empty"); return tmp;
} //判断删除的位置是否正确
// i小于1表示删除第1个位置之前的元素,
// i大于last+1表示删除后一个元素后面的第1个位置的元素。
if (i < 1 || i > lastIndex+1)
{
Console.WriteLine( "Position is error!");return tmp;
}
//删除的是后一个元素
if (i == lastIndex+1)
{
tmp = data[last--];
}
//删除的不是后一个元素
else
{
//元素移动
tmp = data[i-1];
for (int j = i; j <= lastIndex; ++j)
{
data[j] = data[j + 1];
}
}
//修改表长
--lastIndex;
return tmp;
}
public T GetElem(int i)
{
if(i<1||lastIndex==-1)
{
Console.WriteLine("error");
return;
}
return this.data[i-1];
}
}

在上述代码中,我们分析一下删除和插入的操作

算法的时间复杂度分析:顺序表上的删除操作与插入操作一样,时间主要消 耗在数据的移动上在第i个位置删除一个元素,从ai+1到an都要向前移动一个位置,共需要移动n-i个元素,而i的取值范围为 1≤i≤n,当i等于 1 时,需要移动 的元素个数多,为n-1 个;当i为n时,不需要移动元素。设在第i个位置做删除 的概率为pi,则平均移动数据元素的次数为(n-1)/2。这说明在顺序表上做删除操 作平均需要移动表中一半的数据元素,所以,删除操作的时间复杂度为O(n)。

一些额外操作

我们以倒转为例,事实上我们倒转的时候,只需要将第一个和最后一个,第二个和倒数第二个以此类推进行交换即可

public void ReversSeqList(SeqList<int> L)
{
int tmp = 0;
int len = L.GetLength();
for (int i = 0; i<= len/2; ++i)
{
tmp = L[i];
L[i] = L[len - i];
L[len - i] = tmp;
}
}

各位可以尝试一下生成不含重复值顺序表和合并顺序表并有序的排列算法,这里给出一些思路。

  • 去重:先把顺序表 La 的第 1 个元素赋给顺序表 Lb,然后从顺序表 La 的第 2 个元素起,每一个元素与顺序表 Lb 中的每一个元素进行比较,如果不相 同,则把该元素附加到顺序表 Lb 的末尾。
  • 合并排序:依次扫描 La 和 Lb 的数据元素,比较 La 和 Lb 当前数据元素的 值,将较小值的数据元素赋给 Lc,如此直到一个顺序表被扫描完,然后将未完 的那个顺序表中余下的数据元素赋给 Lc 即可。Lc 的容量要能够容纳 La 和 Lb 两个表相加的长度。

Github

BiliBili主页

WarrenRyan's Blog

博客园

.NET Core 数据结构与算法 1-1的更多相关文章

  1. 《数据结构与算法之美》 <01>复杂度分析(上):如何分析、统计算法的执行效率和资源消耗?

    我们都知道,数据结构和算法本身解决的是“快”和“省”的问题,即如何让代码运行得更快,如何让代码更省存储空间.所以,执行效率是算法一个非常重要的考量指标. 那如何来衡量你编写的算法代码的执行效率呢?这里 ...

  2. 数据结构和算法(Golang实现)(25)排序算法-快速排序

    快速排序 快速排序是一种分治策略的排序算法,是由英国计算机科学家Tony Hoare发明的, 该算法被发布在1961年的Communications of the ACM 国际计算机学会月刊. 注:A ...

  3. [GitHub] 75+的 C# 数据结构和算法实现

    C#中标准数据结构和算法的即插即用类库项目 GitHub:https://github.com/aalhour/C-Sharp-Algorithms Watch: 307 Star: 3.4k For ...

  4. 开启基本数据结构和算法之路--初识Graphviz

    在我的Linux刀耕开荒阶段,就想开始重拾C,利用C实现常用的基本数据结构和算法,而数据结构和算法的掌握的熟练程度正是程序的初学者与职业程序员的分水岭. 那么怎么开启这一段历程呢? 按照软件工程的思想 ...

  5. 【转】MySQL索引背后的数据结构及算法原理

    摘要 本文以MySQL数据库为研究对象,讨论与数据库索引相关的一些话题.特别需要说明的是,MySQL支持诸多存储引擎,而各种存储引擎对索引的支持也各不相同,因此MySQL数据库支持多种索引类型,如BT ...

  6. [转]MySQL索引背后的数据结构及算法原理

    摘要 本文以MySQL数据库为研究对象,讨论与数据库索引相关的一些话题.特别需要说明的是,MySQL支持诸多存储引擎,而各种存储引擎对索引的支持也各不相同,因此MySQL数据库支持多种索引类型,如BT ...

  7. MySQL索引背后的数据结构及算法原理【转】

    本文来自:张洋的MySQL索引背后的数据结构及算法原理 摘要 本文以MySQL数据库为研究对象,讨论与数据库索引相关的一些话题.特别需要说明的是,MySQL支持诸多存储引擎,而各种存储引擎对索引的支持 ...

  8. 数据结构与算法JavaScript (一) 栈

    序 数据结构与算法JavaScript这本书算是讲解得比较浅显的,优点就是用javascript语言把常用的数据结构给描述了下,书中很多例子来源于常见的一些面试题目,算是与时俱进,业余看了下就顺便记录 ...

  9. 数据结构与算法 Big O 备忘录与现实

    不论今天的计算机技术变化,新技术的出现,所有都是来自数据结构与算法基础.我们需要温故而知新.        算法.架构.策略.机器学习之间的关系.在过往和技术人员交流时,很多人对算法和架构之间的关系感 ...

随机推荐

  1. 天天动听API

    本次分析的是天天动听API,天天动听有一点比较好,就是搜索返回直接有歌曲播放的地址了,并且有无损的音频 搜索歌曲API:http://so.ard.iyyin.com/s/song_with_out? ...

  2. Flutter - You need to use a different version code for your APK or Android App Bundle because you already have one with version code 1.

    前两天提交了一个版本Google Play,结果今天收到拒绝的邮件,说App内购有问题. 于是把设置里面的支付宝和微信打赏功能关闭,又打了一个aab. 然后上传到Google Play,结果提示 Yo ...

  3. Python面向对象-定制方法

    Python中的class可以定义许多定制方法,可以让我们方便的生成特定的类. 我们之前介绍了__slots__.__len__(),python中还有许多这样的特殊函数: __str__ >& ...

  4. .NET Core Razor Pages中ajax get和post的使用

    ASP.NET Core Razor Pages Web项目大部分情况下使用继承与PageModel中的方法直接调用就可以(asp-page),但是有些时候需要使用ajax调用,更方便些.那么如何使用 ...

  5. 在 Spring Boot 项目中使用 activiti

    新建springBoot项目时勾选activiti,或者在已建立的springBoot项目添加以下依赖: <dependency> <groupId>org.activiti& ...

  6. python通过人脸识别全面分析好友,一起看透你的“朋友圈”

    微信:一个提供即时通讯服务的应用程序,更是一种生活方式,超过数十亿的使用者,越来越多的人选择使用它来沟通交流. 不知从何时起,我们的生活离不开微信,每天睁开眼的第一件事就是打开微信,关注着朋友圈里好友 ...

  7. weblogic启动服务器Authentication denied: Boot identity not valid

    新分配的测试服务器,已经安装好了weblogic,使用命令nohub ./startWeblogic.sh启动weblogic没有问题 登录控制台,点击环境-服务器-新建,一步步完成后,点击部署.选择 ...

  8. PlayJava Day023

    进程:进程是程序的一次动态执行过程,它经历了从代码加载.执行到执行完毕的一个完整过程,这个过程也是进程本身从产生.到发展到最终消亡的过程 多进程:多进程操作系统能同时运行多个进程(程序) 多线程:是指 ...

  9. 易优CMS:channelartlist 获取当前频道的下级栏目的内容列表

    channelartlist 获取当前频道的下级栏目的内容列表   [基础用法] 名称:channelartlist 功能:获取当前频道的下级栏目的内容列表标签 语法: {eyou:channelar ...

  10. JS---DOM---元素创建的不同方式---三种方式,5个案例

    元素创建-----为了提高用户的体验   元素创建的三种方式: 1. document.write("标签的代码及内容"); 2. 对象.innerHTML="标签及代码 ...