C# 顺序表

非常标准的顺序表结构,等同于C#中的List<T>,但是List<T>在排错查询和数据结构替换上存在缺陷,一些情况会考虑使用自己定义的数据结构

1.优化方向 下表使用冒泡排序,可以考虑优化算法


/***************************************
作者: 未闻花语
版本: v1.5
最后修改时间: 2018/05/18
电话: 159****7727
功能&使用方法:
* 泛型顺序表 [Update]
* 1.新增了预扩容功能 (新增了一个构造函数 在创建之初设置其容量大小)
* 2.所有判断相等的方法都是通过 委托传入 包括 “排序”及 “判断是否存在”
* 3.扩容大小为原大小的1.5倍, 如果觉得不合适 可自行调整 一般为1.5倍
* 4.增加了插入函数
* 5.添加了预扩容的安全校验
*
* 优点:
* 1.无需为表示表中对象的关系而增加额外的存储空间
* 2.可以快速的获取表中任一位置的数据
* 3.C#中的List就是使用的这种存储形式
*
* 缺点:
* 1.插入和删除操作 移动的元素过多 时间开销大
* 2.长度增长时对内存开销较大(现在修改为原数据的大小的1.5倍)
* ,会存在内存浪费!一般称为内存碎片。
*
* 适用:
* 适用于数据长度变化不大 且 索取频繁的情况
*
*
* 存在方法:
* <0> ----------- MyArrayList<T>() -------- 无参构造
* <1> ----------- Size() ------------------ 得到使用空间
* <2> ----------- Expansion()(私有)------ 扩容
* <3> ----------- Add(T data) ------------- 添加数据
* <4> ----------- (r)T At(int index) ------ 得到数据
* <5> ----------- Clear() ----------------- 清空数据
* <6> ----------- (r)T this[int index] ---- 得到/设置 数据【索引器】
* <7> ----------- SortSmallToBig() -------- 排序(从小到大)(冒泡排序)
* <8> ----------- Show(Action<T>) --------- 自定义打印
* <9> ----------- Contains(T) ------------- bool类型返回是否包含这个东西
* <10> ---------- Insert(T _data, int _index) 插入
* <11> ---------- Delete(_index) ---------- 删除数据
*
* 存在属性:
* Capacity ------ 容量
* Size ---------- 当前使用空间
***************************************/
#if UNITY_EDITOR
using UnityEngine;
#endif
using System.Collections;
using System;
namespace MyList
{
public class MyArrayList<T>
{
//容量
int m_capacity;
//使用量
int m_size;
//堆 --- 指针
T[] obj;
//构造0 (无参构造)
public MyArrayList()
{
//内存容量 (默认为4)
m_capacity = ;
//空间使用量归0
m_size = ;
//开堆
obj = new T[m_capacity];
}
//构造1 (带参构造)
public MyArrayList(int _capacity)
{
//内存容量
m_capacity = _capacity > ? _capacity : ;
//空间使用量归0
m_size = ;
//开堆
obj = new T[m_capacity];
}
//方法 --- 扩容
void Expansion()
{
//容量 == 使用量
if (m_size == m_capacity)
{
////容量扩大一倍
//m_capacity *= 2;
//容量扩大为原来的1.5倍
m_capacity = (int)(m_capacity * 1.5);
//数据开堆
T[] nt = new T[m_capacity];
//复制数据
for (int i = ; i < m_size; ++i)
{
nt[i] = obj[i];
}
//修改数据结构指针指向
obj = nt;
}
}
//方法 --- 数据添加
public void Add(T data)
{
//扩容
Expansion();
//放入数据
obj[m_size++] = data;
}
//方法 --- 插入
public void Insert(T _data, int _index)
{
//容量检查
Expansion();
//移动数据
for (int i = Size; i > _index; i--)
{
obj[i] = obj[i - ];
}
//填入数据
obj[_index] = _data;
m_size++;
} //方法 --- 得到数据[下标索引]
public T At(int index)
{
//参数检查
if (index < || index >= m_size)
return default(T);
else
return obj[index];
}
//方法 --- 清空
public void Clear()
{
//使用空间修改为0就可以了
m_size = ;
}
//索引器a
public T this[int index]
{
set
{
//设置数据 在 范围内
if (index >= && index < m_size)
{
obj[index] = value;
}
}
get
{
if (index >= && index < m_size)
return obj[index];
else
return default(T);
}
}
//声明委托
//case 1 -------------- Left > Right
//case 0 -------------- Left == Right
//case -1 -------------- Left < Right
public delegate int CompareTo(T _objLeft, T _objRight);
//方法 --- 排序(冒泡)
public void SortSmallToBig(CompareTo CTF)
{
//冒泡排序
for (int i = ; i < m_size; ++i)
{
for (int j = m_size - ; j > i; --j)
{
if (CTF(obj[i], obj[j]) > )
{
T temp = obj[i];
obj[i] = obj[j];
obj[j] = temp;
}
}
}
}
//遍历显示(C#控制台显示)
public void Show(Action<T> _func)
{
//遍历
for (int i = ; i < m_size; ++i)
{
//这个显示方式比
_func(obj[i]);
}
}
//遍历查找
public bool Contains(T t, CompareTo CTF)
{
//遍历
for (int i = ; i < m_size; ++i)
{
if (CTF(t, obj[i]) == )
{
return true;
}
}
//否则return false
return false;
}
//属性 ----- 返回容量
public int Capacity
{
get { return m_capacity; }
}
//属性 ----- 返回使用空间
public int Size
{
get { return m_size; }
}
//删除数据
public void Delete(int _index)
{
if (_index < || _index > m_size - )
return;

        for (int i = _index; i < m_size; ++i)
             {
                  if (i - 1 < 0)
                     continue;
                  obj[i - 1] = obj[i];
             }

        m_size--;

        }
}
}

C# 链表(单向无头)

单向非闭环,无表头的链表,一般用于非队尾数据需要进行频繁删减的情况,由于没有表头所有排序算法写的有点low

1.优化方向,改成双向链表,但是改成双向链表会花点时间因为指针的操作比较多,很容易出现闭环的情况如下图


/***************************************
作者: 未闻花语
版本: v1.2
最后修改时间: 2018/05/20
电话: 159****7727
功能&使用方法:
* 泛型单向链表 [Update]
* 修改了Show函数的一个bug
* 没有表头!!
*
* 优点:
* 1.自然是插入和排序时,速度较快
* 2.当元素数目区间不确定时,不会有较大空间的浪费
*
* 缺点:
* 1.平凡的内存申请与销毁(可通过 修改成带缓存的链表或使用对象池来解决)
* 2.相较于顺序表 略微增加了内存开销
* 3.相较于顺序表 下标查询略微缓慢
*
* 适用:
* 适用于数据长度不确定,又存在平凡删减的情况
*
*
* 存在方法:
* <0> ----------- Add(T data) ------------- 添加数据
* <1> ----------- (r)T At(int index) ------ 得到数据[索引器]
* <2> ----------- Delete(_index) ---------- 删除数据
* <3> ----------- Inset(T _data, int _index) 插入数据
* <4> ----------- Clear() ----------------- 清空数据
*
* 存在属性:
* Capacity ------ 容量
* Size ---------- 当前使用空间
***************************************/
using System;
class Node<T>
{
private T m_data;
public T Data { get { return m_data; } set { m_data = value; } }
private Node<T> m_next;
public Node<T> Next { get { return m_next; } set { m_next = value; } }
public Node(T _data)
{
Data = _data;
this.Next = default(Node<T>);
}
}
public class JWMyLinkList<T>
{
//表头
Node<T> m_head;
//表长
private int m_size;
public int Size { get { return m_size; } }
//构造
public JWMyLinkList()
{
m_size = 0;
m_head = null;
}
//添加数据
public void Add(T _data)
{
Node<T> nNote = new Node<T>(_data);
if (Size == 0)
{
m_head = nNote;
}
else
{
Node<T> p = m_head;
while (p.Next != null)
{
p = p.Next;
}
p.Next = nNote;
}
m_size++;
}
//删除数据
public bool Delete(int _index)
{
if (_index < 0 || _index > Size - 1)
return false; if (_index == 0)
{
m_head = m_head.Next;
m_size--;
return true;
} Node<T> preP = m_head;
Node<T> afterP = m_head;
for (int i = 0; i < _index - 1; ++i)
preP = preP.Next;
if (_index == Size - 1)
afterP = null;
else
{
for (int i = 0; i < _index + 1; ++i)
afterP = afterP.Next;
}
preP.Next = afterP;
m_size--;
return true;
}
//插入数据
public bool Insert(T _data, int _index)
{
if (_index < 0 || _index > Size - 1)
return false;
Node<T> nNote = new Node<T>(_data);
if (_index == 0)
{
nNote.Next = m_head;
m_head = nNote;
m_size++;
return true;
}
Node<T> preP = m_head;
for (int i = 0; i < _index - 1; ++i)
preP = preP.Next;
nNote.Next = preP.Next;
preP.Next = nNote;
m_size++;
return true;
}
//得到数据
public T At(int _index)
{
T r = default(T);
if (_index < 0 || _index > Size - 1)
return r;
Node<T> P = m_head;
for (int i = 0; i < _index; ++i)
P = P.Next;
r = P.Data;
return r;
}
//索引器a
public T this[int _index]
{
set
{
//设置数据 在 范围内
if (_index >= 0 && _index < m_size)
{
Node<T> P = m_head;
for (int i = 0; i < _index; ++i)
P = P.Next;
P.Data = value;
}
}
get
{
if (_index >= 0 && _index < m_size)
{
Node<T> P = m_head;
for (int i = 0; i < _index; ++i)
P = P.Next;
return P.Data;
}
else
return default(T);
}
}
//清除数据
public void Clear()
{
if (m_size < 1)
return;
Node<T> A = m_head;
Node<T> B = A;
do
{
B = B.Next;
A.Next = null;
A = B;
} while ((B != null));
m_size = 0;
}
//声明委托
//case 1 -------------- Left > Right
//case 0 -------------- Left == Right
//case -1 -------------- Left < Right
public delegate int CompareTo(T _objLeft, T _objRight);
//判断存在 CompareTo CTF
public bool Contains(T _data, CompareTo CTF)
{
Node<T> A = m_head;
while (A != null)
{
if (CTF(A.Data, _data) == 0)
return true;
A = A.Next;
}
return false;
}
//遍历显示
public void Show(Action<T> _func)
{
if (m_size == 0)
return;
//遍历
Node<T> A = m_head;
while (A != null)
{
//这个显示方式比
_func(A.Data);
A = A.Next;
}
}
//方法 --- 排序(冒泡)
public void SortSmallToBig(CompareTo CTF)
{
//安全校验
if (Size < 2)
return;
Node<T> A = m_head;
Node<T> B = m_head;
//冒泡排序
for (int i = 0; i < m_size; ++i)
{
A = m_head;
B = A;
for (int j = m_size - 1; j > i; --j)
{
if (CTF(A.Next.Data, A.Data) < 0)
{
if (m_head == A)
{
m_head = A.Next;
A.Next = A.Next.Next;
m_head.Next = A;
B = m_head;
}
else
{
B.Next = A.Next;
A.Next = B.Next.Next;
B.Next.Next = A;
B = B.Next;
}
}
else
{
if (m_head != A)
{
B = B.Next;
}
A = A.Next; }
}
}
}
}

  


测试运行程序

用于测试上述表的运行程序 & 结果

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
//包含命名空间 MyList
using MyList;
namespace DataStructure
{
class Program
{
static void Main(string[] args)
{
//随机名字的数组
string[] rNameSpace = new string[] {"蒋伟","吴悦","曾真","刘芸",
"珠海妮","李小满","薛涵","邱伊雨","李晶晶","戴林江","代安东","黄挺",
"陈政","叶小青","徐逸"};
//随机用户数
//(PS:测试用,没写限制 所以不要太大 最好不要超过10个)
const int studentCount = ;
//开堆
//var team0 = new MyArrayList<Student>(3);
var team0 = new MyLinkList<Student>();
Student[] students = new Student[studentCount];
//随机出现数据 并添加 当随机种子一样是数据一样
Random ra = new Random();
for (int i = ; i < studentCount;)
{
int id = ra.Next(, );
string name = rNameSpace[ra.Next(, rNameSpace.Length)];
bool isGirl = ra.Next(, ) == ? false : true;
Student s0 = new Student(id, name, isGirl);
//查找是否有相同的属性
if (team0.Contains(s0, StudentJudgeFunc0))
{
continue;
}
else
{
team0.Add(s0);
++i;
}
}
//遍历显示 & 属性调用
Console.WriteLine(""); Console.WriteLine("==================== 分割线 ===================="); Console.WriteLine("");
team0.Show(ShowFunc);
Console.WriteLine();
//Console.WriteLine(string.Format("当前顺序表 \t--- \t容量 :\t\t{0}", team0.Capacity));
Console.WriteLine(string.Format("当前XX表 \t--- \t大小 :\t\t{0}", team0.Size));
Console.WriteLine(string.Format("下表索引器测试 \t--- \t下标3姓名 :\t{0}", team0[].m_name));
Console.WriteLine(""); Console.WriteLine("==================== 排序后 ===================="); Console.WriteLine("");
team0.SortSmallToBig(StudentJudgeFunc0);
team0.Show(ShowFunc);
Console.WriteLine(""); Console.WriteLine("==================== 插入&删除测试 ===================="); Console.WriteLine("");
team0.Insert(new Student(, rNameSpace[], true), );
team0.Delete();
team0.Show(ShowFunc);
Console.WriteLine(""); Console.WriteLine("==================== 清空测试 ===================="); Console.WriteLine("");
team0.Clear();
team0.Show(ShowFunc);
}
//比较函数
static int StudentJudgeFunc0(Student s0, Student s1)
{
if (s0.m_id == s1.m_id || s0.m_name.Equals(s1.m_name))
return ;
if (s0.m_id > s1.m_id)
return ;
else
return -;
}
//显示函数
static void ShowFunc(Student _stu)
{
Console.WriteLine(string.Format("{1}\t[{0}]\t ---- \t{2}", _stu.m_id, _stu.m_name, _stu.m_isGirl ? "Gril" : "Boy"));
}
}
class Student
{
//学号
public int m_id;
//姓名
public string m_name;
//性别
public bool m_isGirl;
//构造
public Student(int _id, string _name, bool _isGirl)
{
m_id = _id;
m_name = _name;
m_isGirl = _isGirl;
}
}
}

备注:

链表 Clear While循环条件错误,已经修改!

C#顺序表 & 单向链表(无头)的更多相关文章

  1. [Python] 数据结构--实现顺序表、链表、栈和队列

    说明: 本文主要展示Python实现的几种常用数据结构:顺序表.链表.栈和队列. 附有实现代码. 来源主要参考网络文章. 一.顺序表 1.顺序表的结构 一个顺序表的完整信息包括两部分,一部分是表中元素 ...

  2. 【PHP数据结构】线性表?顺序表?链表?别再傻傻分不清楚

    遵从所有教材以及各类数据结构相关的书书籍,我们先从线性表开始入门.今天这篇文章更偏概念,是关于有线性表的一个知识点的汇总. 上文说过,物理结构是用于确定数据以何种方式存储的.其他的数据结构(树.图). ...

  3. 线性表 及Java实现 顺序表、链表、栈、队列

    数据结构与算法是程序设计的两大基础,大型的IT企业面试时也会出数据结构和算法的题目, 它可以说明你是否有良好的逻辑思维,如果你具备良好的逻辑思维,即使技术存在某些缺陷,面试公司也会认为你很有培养价值, ...

  4. K:顺序表和链表的比较

     顺序表和链表是线性表的两种基本实现形式(链表还有多种变化形式),对于这两种实现方式,没有一种方法可以称是最好的,他们各自有着各自的特点和优缺点,适用于不同的应用场景.  与顺序表相比,链表较为灵活, ...

  5. 数据结构中的顺序表和链表(Python语言)

    转载:https://blog.csdn.net/weixin_43187669/article/details/96426362 算法是为了解决实际问题而设计的,数据结构是算法需要处理的问题载体. ...

  6. c数据结构 顺序表和链表 相关操作

    编译器:vs2013 内容: #include "stdafx.h"#include<stdio.h>#include<malloc.h>#include& ...

  7. java实现顺序表、链表、栈 (x)->{持续更新}

    1.java实现节点 /** * 节点 * @luminous-xin * @param <T> */ public class Node<T> { T data; Node& ...

  8. 数据结构学习java(一点五)链式顺序表(链表)

    java中没有将指针暴露给用户(以前做过看过一篇文章写有java中是有指针的,只是被藏起来了),所以得使用引用的方式. 何为引用请看下面这篇文章(写的很不错,当然肯定比我写的好): https://w ...

  9. C++模板的实现(模板函数和模板类,附带模板实现顺序表和链表代码)

    文章链接:https://blog.csdn.net/qq_38646470/article/details/80209469

随机推荐

  1. 序列化与反序列化之Kryo

    序列化:把对象转换为字节序列的过程称为对象的序列化. 反序列化:把字节序列恢复为对象的过程称为对象的反序列化. 需要序列化的情况: 当你想把的内存中的对象状态保存到一个文件中或者数据库中时候: 当你想 ...

  2. [Python]查询oracle导出结果至Excel并发送邮件

    环境:Linux +python2.7+oracle11g 1.提前安装xlwt(excel写入操作模块),cx_Oracle(oracle操作模块) cx_Oracle的安装步骤详见链接:https ...

  3. JQ attr prop 区别

    解决方法:使用prop属性代替attr属性 一.Attr除 checked, selected, 或 disabled状态属性外,其余的属性均可用attr()设置和修改.$("img&quo ...

  4. 关于http以及aphace配置https

    我是通过腾讯云配置的ssl.   网站:www.xian029.cn 免费申请,然后通过phpstudy  来配置的. 密码学:   研究密码编码与解码的学科,可以分为编码学和破译学.   HTTPS ...

  5. Halcon常用算子02

    threshold:阈值分割       minGray<=g<=maxGray select_shape:选取特定区域(Region) regiongrowing:区域生长法分割图像获得 ...

  6. javascript中的类型检测

    最常见的是使用 typeof 来判断数据类型 可以区分4种基本类型,即 “number”,”string”,”undefined”,”boolean”,第5种基本类型null类型返回值为object( ...

  7. Android Studio修改项目中整体包名

    莫名的需求,要把之前的apk分成三个不同的apk,还要在应用市场能够上线,麻麻滴这样一听那还不要各个apk包的包名不同以及apk签名文件也不同嘛(签名文件一般也用不同,为防止上线冲突嘛).所以就亲自尝 ...

  8. Yii2.0关闭自带的debug功能

    1.找到相应模块的config文件夹的main-local.php文件注释相关代码,如下: 2.将web下面的两个入口文件改成false  index.php  index-test.php

  9. maven插件后报错:org.apache.maven.archiver.MavenArchiver.getManifest(org.apache.maven.project

    在给eclipse换了高版本的maven插件后,引入jar包报如下的错误: org.apache.maven.archiver.MavenArchiver.getManifest(org.apache ...

  10. RobotFramework 模拟http接口登录自动化脚本

    RobotFramework 模拟自动化登录脚本思路: 先获取页面cookie值,然后根据cookie值加上请求体提交登录: 一.获取cookie: 以下脚本获取cookie值,并把改脚本封装为关键字 ...