当前位置:  编程技术>.net/c#/asp.net

C#数据结构与算法揭秘三 链表

    来源: 互联网  发布时间:2014-10-15

    本文导语:  上文我们讨论了一种最简单的线性结构——顺序表,这节我们要讨论另一种线性结构——链表。 什么是链表了,不要求逻辑上相邻的数据元素在物理存储位置上也相邻存储的线性结构称之为链表。举个现实中的例子吧,假如一...

上文我们讨论了一种最简单的线性结构——顺序表,这节我们要讨论另一种线性结构——链表。

什么是链表了,不要求逻辑上相邻的数据元素在物理存储位置上也相邻存储的线性结构称之为链表。举个现实中的例子吧,假如一个公司召开了视频会议的吧,能在北京总公司人看到上海分公司的人,他们就好比是逻辑上相邻的数据元素,而物理上不相连。这样就好比是个链表。 链表分为①单链表,②单向循环链表,③双向链表,④双向循环链表。

介绍各种各样链表之前,我们要明白这样一个概念。什么是结点。在存储数据元素时,除了存储数据元素本身的信息外,还要存储与它相邻的数据元素的存储地址信息。这两部分信息组成该数据元素的存储映像(Image),称为结点(Node)。在c语言这些面向过程语言中,实现节点是通过指针的形式,在。net中,是通过模拟指针——类对象嵌套的形式。

然后,首先,介绍单链表。如果结点的引用域只存储该结点直接后继结点的存储地址, 则该链表叫单链表(Singly Linked List)。把该引用域叫 next。单链表结点的结构如图所示,图中 data表示结点的数据域。

现实中,就像一队盲人过马路。如图所示

   

把单链表结点看作是一个类,类名为 Node。单链表结点类的实现如下所示。 

代码如下:

public class Node
{
//一队盲人过马路 存储的是盲人的姓名
private T data; //数据域 存储数据的对象
//一队盲人过马路 指向的是下一个盲人对象。
private Node next; //引用域 指向下一个对象

//构造器
public Node(T val, Node p)
{
data = val;
next = p;
}

//构造器
public Node(Node p)
{
next = p;
}

//构造器
public Node(T val)
{
data = val;
next = null;
}

//构造器
public Node()
{
data = default(T);
next = null;
}

//数据域属性
public T Data
{
get
{
return data;
}
set
{
data = value;
}
}

//引用域属性
public Node Next
{
get
{
return next;
}
set
{
next = value;
}
}
}


下图是线性表(a1,a2,a3,a4,a5,a6)对应的链式存储结构示意图。

单链表类 LinkList源代码的实现说明如下所示。首先申明一下,他继承与IListDS这个接口。

//这是一个盲人过马路的类的模拟

public class LinkList : IListDS { 

//排在第一个位置的盲人

private Node head; //单链表的头引用

//头引用属性
public Node Head
{
get
{
return head;
}

set
{
head = value;
}
}

//构造器

//开始的时候一个盲人都没有,头结点指向为空的位置。没有排头的盲人
public LinkList()
{
head = null;
}

 

//这里我们求盲人队伍的长度,从第一个盲人数起,然后第二个,第三个。就以此类推。。。这样子盲人的队伍的长度就得出来了啊。

//求单链表的长度
public int GetLength()
{
Node p = head;

int len = 0;
while (p != null)
{
++len;
p = p.Next;
}
return len;
}

 

//不让盲人排队,就是让这个队的头都不存在

//清空单链表
public void Clear()
{
head = null;
}

 

//判断一个盲人队列的是不是为空,看他的头部是不是有人

//判断单链表是否为空
public bool IsEmpty()
{
if (head == null) 
{
return true;
}
else
{
return false;
}
}

//在单链表的末尾添加新元素
public void Append(T item)
{
Node q = new Node(item);
Node p = new Node();
//这里如果没有盲人排队的话,就在队列的头部进行了 


if (head == null)
{
head = q;
return;
}
//不懂的,一切尽在图例中

//如果有人排队,就从头遍历,让他从没人的地方加入到队伍中去并且把这个队列的指针 指向后面。
p = head;
while (p.Next != null)
{
p = p.Next;
}

p.Next = q;

不懂的一切尽在图例中

这个方法的算法复杂度是O(n)
}

//就是在一队中增加了插队的人员

//在单链表的第i个结点的位置前插入一个值为item的结点
public void Insert(T item, int i)
{
if (IsEmpty() | | i < 1)
{
Console.WriteLine("List is empty or Position is error!");
return;
}
//是头结点的位置,就把他的头执政指向与他,把另外指针与他  

if (i == 1)
{
Node q = new Node(item);
q.Next = head;
head = q;
return;
}
//不懂的,如图所示:

//而这个是将其循环到队列相应的位置,在将从头其插入到这个位置

Node p = head;
Node r = new Node();
int j = 1;

while (p.Next != null&& j < i)
{
r = p;
p = p.Next;
++j;
}

if (j == i)
{
Node q = new Node(item);
q.Next = p;
r.Next = q;
}

一切尽在图例中

}

 这个方法的算法复杂度O(n)

 

//删除单链表的第i个结点
public T Delete(int i)
{

//是不是盲人排队的 或者排队的位置不是正确的   这就返回了一个错误信息
if (IsEmpty()|| i < 0)
{
Console.WriteLine("Link is empty or Position is
error!");
return default(T);
}
//是头结点的 的就返回  第二个节点顶到第一个节点的位置

Node q = new Node();

if (i == 1)
{
q = head;
head = head.Next;
return q.Data;
}
此步骤为O(1)  

 

//不是的头位置的吧,就寻找相应位置的节点,在进行删除。他这个排队前面的人指向后面的人。这就是新的队伍了  没找到,就返回错误。
Node p = head;
int j = 1;

while (p.Next != null&& j < i)
{
++j;
q = p;
p = p.Next;
}

if (j == i)
{
q.Next = p.Next;
return p.Data;
}
else
{
Console.WriteLine("The ith node is not exist!");
return default(T);
}

不懂的如图所示:

此方法的运行时间复杂度是O(n)
}

//获得单链表的第i个数据元素

//知道队伍 我要查询出队伍中第n个人是那位,
public T GetElem(int i)
{

//如果是空的就返回为错误的结果
if (IsEmpty())
{
Console.WriteLine("List is empty!");
return default(T);
}

//从图接点数  第n个的结果了
Node p = new Node();
p = head;
int j = 1;

while (p.Next != null&& j < i)
{

++j;
p = p.Next;
}
//有着 则返回  没有就返回错误

if (j == i)
{
return p.Data;
}
else
{
Console.WriteLine("The ith node is not exist!");
return default(T);
}
}

不懂的,一切尽在图例中。

此方法的时间的复杂度是O(n)

//我要查询张山的位于队伍的第几个位置

//在单链表中查找值为value的结点
public int Locate(T value)
{

//空返回为假的的  
if(IsEmpty())
{
Console.WriteLine("List is Empty!");
return -1;
}

Node p = new Node();
p = head;
int i = 1;

//从头遍历 比较器 相等的   返回为相应的索引

while (!p.Data.Equals(value)&& p.Next != null)
{
P = p.Next;
++i; 
}
不懂的,如图所示:


return i;

这个算法复杂度是O(n2)
}

}

这节我们讨论链表的基本操作,并且画图以证明,下届中我们将讨论双向链表,环形链表 应用举例。


    
 
 

您可能感兴趣的文章:

  • C#数据结构之循环链表的实例代码
  • C#数据结构揭秘一
  • C#数据结构与算法揭秘一
  • C#数据结构与算法揭秘四 双向链表
  • C#数据结构与算法揭秘二 线性结构
  • C#数据结构与算法揭秘二
  • C#数据结构与算法揭秘五 栈和队列
  • <<大话数据结构>>中冒泡排序算法改进
  • 数据结构和算法教程 OpenDSA
  • 看LINUX的内核要不要硬件、数据结构、算法、汇编
  • 哪里有《数据结构与算法分析(JAVA版)》的电子书下载,谢了:)
  • 那个大侠可以推荐一本关于java的数据结构和算法的书?  
  • 请问哪里有《数据结构与算法分析(JAVA版)》的电子书下载????
  • 看过《数据结构与算法》(java版)谈谈一下感想?
  • C++ 冒泡排序数据结构、算法及改进算法
  • java数据结构和算法学习之汉诺塔示例
  •  
    本站(WWW.)旨在分享和传播互联网科技相关的资讯和技术,将尽最大努力为读者提供更好的信息聚合和浏览方式。
    本站(WWW.)站内文章除注明原创外,均为转载、整理或搜集自网络。欢迎任何形式的转载,转载请注明出处。












  • 相关文章推荐
  • 基于Key-Value的NOSQL数据库Redis的数据结构及常用相关命令介绍
  • 强人,linux下驱动相关数据结构和usb设备数据结构之间的功能分析
  • Oracle数据库(Oracle Database)体系结构及基本组成介绍
  • GNU汇编fill填充一个数据结构使得另一个数据结构全部清零
  • 数据结构:图(有向图,无向图),在Python中的表示和实现代码示例
  • 请问:在用proc方式往数据库插入数据时,我能不能定义一个结构体,它与表的每一项对应,将结构体赋好值后,再只将这个结构体插入表中,这行不行啊?
  • mysql 命令大全及导入导出表结构或数据
  • 请教:请问java中存放数据库中的记录,用什么数据结构?(hashtable?vector?还是别的?)
  • 通用数据结构库 GDSL
  • 如何把一个数组转化为一个数据结构,如ArrayList。
  • 多维数据结构 mdds
  • C数据结构库 liblfds
  • 一个新的JavaScript数据结构 stream.js
  • 数据结构
  • 高手帮帮忙!vi中如何实现跳转到任意结构体或函数的声明处,包括系统库中声明的函数和数据结构?
  • 请教各位,数据结构在工程中到底有什么应用呢
  • 放假了,想用java数据结构,请问大虾们该如何开始?
  • sem_t的数据结构是什么?
  • 数据结构库 libx1f4l2
  • 请问哪里有关于JAVA版的数据结构的书当
  • java 与数据结构


  • 站内导航:


    特别声明:169IT网站部分信息来自互联网,如果侵犯您的权利,请及时告知,本站将立即删除!

    ©2012-2021,,E-mail:www_#163.com(请将#改为@)

    浙ICP备11055608号-3