C#数据结构-静态链表
对于双向链表中的节点,都包括一个向前、向后的属性器用于指向前后两个节点,对于引用类型,对象存储的是指向内存片段的内存指针,那么我们可以将其简化看作向前向后的两个指针。
现在我们将引用类型替换为值类型int,将链用数组代替,向后的指针替换为数组的下标,那么此时的链我们称为静态链表(或者说是单向静态链表)。
不多说,直接上代码(代码已做注解)
public class Node<T>
{ public T data { get; set; } public int next { get; set; } public Node(T item)
{
data = item;
}
}
public class StaticLink<T>
{
public int count { get; set; } = 0;
public Node<T>[] link { get; set; }
public int minSize { get; set; } = 10;
public int extendSize { get; set; } = 10;//扩容步长
public StaticLink()
{
//第一个节点为空节点,不存储内容,同时,第一个节点的next存放备用链表的第一个节点(备用链表——数组内可以用于存储内容的处于空值时的节点连接成的表)
//初始化,静态链表的长度为10;
link = new Node<T>[minSize];
for (int i = 0; i < minSize; i++)
{
//i=0时,由于链表为空,则备用链表的第一个节点也就是1
link[i] = new Node<T>(default(T));
link[i].next = i + 1;
}
//初始化,静态链表的结尾next 指向第一个节点(除头节点外)
link[minSize - 1].next = 1;
count++;
}
private int Malloc()
{
//取得静态链表-备用链表中的第一个节点(取出待用,存储内容)
int i = link[0].next;
if (i > 0)
{
//同时,移除备用链表的第一个节点,
link[0].next = link[i].next;
//取到链表的最后一个元素时,扩容。
if (i >= minSize - 1)
{
//todo 不翻倍扩容,采用定值步长扩容~
//todo 暂不实现
}
}
return i;
}
/// <summary>
/// 在链表的结尾附加
/// </summary>
/// <param name="node"></param>
public void Append(T node)
{
Insert(count, node);
}
/// <summary>
/// 指定位置插入节点
/// </summary>
/// <param name="index"></param>
/// <param name="node"></param>
public void Insert(int index, T node)
{
//要插入的节点需要在链表的范围内
if (index > count || index < 1)
throw new IndexOutOfRangeException("索引超出界限");
//由于时插入节点,所以此处我们需要从备用链表取出一个空节点。
int maxIndex = Malloc();
int k = minSize - 1;
Node<T> newNode = new Node<T>(node);//创建一个节点 if (count == 1)
newNode.next = 0;
else
{
//取链表最后一个节点的next;
for (int i = 1; i <= index -1; i++)
{
k = link[k].next;
}
newNode.next = link[k].next;
link[k].next = maxIndex;
}
link[maxIndex] = newNode;
count++;
}
/// <summary>
/// 根据索引删除
/// </summary>
/// <param name="index"></param>
public void Del(int index)
{
//去除头节点,并判断索引要在链表范围内
if (index < 1 || index > count)
throw new IndexOutOfRangeException("索引超出界限");
int k = minSize - 1;
//通过链取得前一个节点 -时间复杂度O(n)
for (int j = 1; j <= index - 1; j++)
{
k = link[k].next;
}
int beforeNodeNext = link[k].next;//获取前一个节点的next;
link[k].next = link[beforeNodeNext].next;//跳过要删除的节点
link[beforeNodeNext].next = link[0].next;//将释放除来的节点接入备用链
link[0].next = beforeNodeNext;//将当前释放的节点放入到备用的第一个节点。-待用
count--;
}
/// <summary>
/// 展示链节点
/// </summary>
public void showAll()
{
for (int i = 1; i <= count; i++)
{
Console.WriteLine($"index:{link[i].next},data:{link[i].data}");
}
}
}
测试:
class Program
{
static void Main(string[] args)
{
StaticLink<string> link = new StaticLink<string>();
link.Append("第一位");
link.Append("第二位");
link.Append("第三位");
link.Insert(2,"第四位,插入到二的位置");
link.Append("第五位");
link.Append("第六位");
link.Append("第七位");
link.Del(6); link.showAll(); Console.ReadLine();
}
}
打印结果:


C#数据结构-静态链表的更多相关文章
- 【Java】 大话数据结构(3) 线性表之静态链表
本文根据<大话数据结构>一书,实现了Java版的静态链表. 用数组描述的链表,称为静态链表. 数组元素由两个数据域data和cur组成:data存放数据元素:cur相当于单链表中的next ...
- Java数据结构-线性表之静态链表
静态链表的定义: 节点由一个一维数组和一个指针域组成,数组用来存放数据元素,而指针域里面的指针(又称游标)用来指向下一个节点的数组下标. 这种链表称之为静态链表. 链表中的数组第一个和最后一个位置须要 ...
- java与数据结构(2)---java实现静态链表
结点类 1 //结点类 2 class Node<T> { 3 private T data; 4 private int cursor; 5 6 Node(T data, int cur ...
- 静态链表C语言数据结构
静态链表就是将数组实现单链表: int Malloc_SLL(StaticLinkList space) { int i = space[0].cur;//取得第一个头节点的下标 if( space[ ...
- 静态链表的C实现(基于数据结构 严蔚敏)
静态链表是利用一维数组实现逻辑上的单链表结构,结点的逻辑上相邻但物理位置上不一定相邻,因为内存分配上是一次性的,故称为静态. 特点: 预先需要一片连续的存储空间: 非随机存取: 无现成的"内 ...
- 【数据结构】单链表&&静态链表详解和代码实例
喜欢的话可以扫码关注我们的公众号哦,更多精彩尽在微信公众号[程序猿声] 01 单链表(Singly Linked List ) 1.1 什么是单链表? 单链表是一种链式存储的结构.它动态的为节点分配存 ...
- 数据结构6: 静态链表及C语言实现
本节继续介绍线性表的另外一种链式表示——静态链表.(前面介绍的链表称为 动态链表 ). 逻辑结构上相邻的数据元素,存储在指定的一块内存空间中,数据元素只允许在这块内存空间中随机存放,这样的存储结构生成 ...
- c数据结构链式存储-静态链表
#include "string.h" #include "ctype.h" #include "stdio.h" #include &qu ...
- 静态链表实现(A-B)+(B-A)【代码】
-----------------------------------------------第一次发代码,写在前面------------------------------------------ ...
随机推荐
- Codeforces 1389 题解(A-E)
AC代码 A. LCM Problem 若\(a < b\),则\(LCM(a,b)\)是\(a\)的整数倍且\(LCM(a,b) \ne a\),所以\(LCM(a,b) \ge 2a\),当 ...
- ThreadLocal是什么?谈谈你对他的理解
1.ThreadLocal是什么 从名字我们就可以看到ThreadLocal叫做线程变量,意思是ThreadLocal中填充的变量属于当前线程,该变量对其他线程而言是隔离的.ThreadLocal为变 ...
- PHP的九个超全局变量
1. 什么是超全局变量 PHP官网:超全局变量 超全局变量就是在全部作用域中始终可用的内置变量. 全局作用域.函数作用域都可以使用的PHP内置变量. 在函数或方法中无需执行 global $varia ...
- 为什么互联网巨头们纷纷使用Git而放弃SVN?(内含Git核心命令与原理总结)
写在前面 最近发现很多小伙伴对于工作中的一些基本工具的使用还不是很了解,比如:Git这个分布式的代码管理仓库,很多小伙伴就不是很了解,或者说不是很熟悉.甚至有些小伙伴都没听说过Git,就只会用个SVN ...
- 乔悟空-CTF-i春秋-Web-SQLi
2020.09.05 今天注定是高产的一天,这题真是坑,不看wp真的不会做,现在回头来复习一遍. 做题 题目 题目地址 做题 这题坑人的地方就在于重定向了两次,并且重要信息在第一次里藏着,第二次还给了 ...
- vue项目Windows Server服务器部署IIS设置Url重写
1.将vue项目使用npm run build命令打包后将dist文件夹内的文件全部拷贝到服务器. 2.IIS添加应用程序池,.NET CLR版本选择无托管代码 3.添加网站,应用程序池选择刚刚添加的 ...
- Node.js 从零开发 web server博客项目[express重构博客项目]
web server博客项目 Node.js 从零开发 web server博客项目[项目介绍] Node.js 从零开发 web server博客项目[接口] Node.js 从零开发 web se ...
- matlab中如何定义函数
首先建立M文件或直接点击(File/New/Function)建立函数文件,其中函数文件的格式是: function [输出变量] = 函数名称(输入变量) % 注释 % 函数体 如下所示,是编写的一 ...
- nginx如何写日志
写日志函数为ngx_log_error_core,位于src/core/ngx_log.c:89行核心代码如下:while (log) { if (log->log_level < lev ...
- mysql 事务、隔离级别
一.事务的四大特性(ACID) 1.原子性(Atomicity):事务开始后所有操作,要么全部做完,要么全部不做,不可能停滞在中间环节.事务执行过程中出错,会回滚到事务开始前的状态,所有的操作就像没有 ...