|
|
using System;
|
|
|
using System.Collections.Generic;
|
|
|
using System.Text;
|
|
|
using System.Net;
|
|
|
using System.Net.Sockets;
|
|
|
namespace Dat2Bin
|
|
|
{
|
|
|
public class LinkList
|
|
|
{
|
|
|
/// <summary>
|
|
|
/// 链表长度
|
|
|
/// </summary>
|
|
|
private int _length;//每次做插入操作,加一,删除操作减一
|
|
|
public int Length
|
|
|
{
|
|
|
get { return _length; }
|
|
|
}//链表长度的接口只读。
|
|
|
private Node _head;//链表头
|
|
|
public Node head
|
|
|
{
|
|
|
get { return _head; }
|
|
|
}
|
|
|
|
|
|
private Node _end;//链表尾
|
|
|
public Node End
|
|
|
{
|
|
|
get { return _end; }
|
|
|
}
|
|
|
|
|
|
/// <summary>
|
|
|
/// 查找索引值index个链表节点。
|
|
|
/// </summary>
|
|
|
/// <param name="index"></param>
|
|
|
/// <param name="flag"></param>
|
|
|
/// <returns></returns>
|
|
|
private Node FindNodeByIndex(int index)
|
|
|
{
|
|
|
//如果越界则抛出异常。
|
|
|
//异常包括有,长度为0,index为0也为异常。index<0则为越界。
|
|
|
if (_length <= index || index < 0) throw new IndexOutOfRangeException("索引超出了链表界限。");
|
|
|
Node flag = null;
|
|
|
int hcount = index;//从头遍历的开销
|
|
|
int ecount = _length - index - 1;//从尾遍历的开销。
|
|
|
//如果从头查找的开销小于等于从尾查找的开销,就从头开始查。
|
|
|
if (hcount <= ecount)
|
|
|
{
|
|
|
flag = _head;
|
|
|
int count = hcount;//关键一步,因为是双向链表
|
|
|
//开始移动标记,直到移到要找到的节点位置
|
|
|
while (count > 0)
|
|
|
{
|
|
|
flag = flag.Next;
|
|
|
count--;
|
|
|
}
|
|
|
}
|
|
|
else
|
|
|
{
|
|
|
flag = _end;
|
|
|
int count = ecount;//关键一步,因为是双向链表
|
|
|
//开始移动标记,直到移到要找到的节点位置
|
|
|
while (count > 0)
|
|
|
{
|
|
|
flag = flag.Pre;
|
|
|
count--;
|
|
|
}
|
|
|
}
|
|
|
//此时的flag位置标记了
|
|
|
return flag;
|
|
|
}
|
|
|
public LinkList()
|
|
|
{
|
|
|
//新建一个空链表,长度为0
|
|
|
_head = null;
|
|
|
_end = null;
|
|
|
_length = 0;
|
|
|
}
|
|
|
|
|
|
/// <summary>
|
|
|
/// 把T类型的data装入链表,位置在链表的最后端
|
|
|
/// </summary>
|
|
|
/// <param name="data"></param>
|
|
|
/// <returns></returns>
|
|
|
public void Add(string fileName, string SafeFileName, DateTime fileStartTime, DateTime fileEndTime, HEADInfo file_head)
|
|
|
{
|
|
|
//新建一节点
|
|
|
Node newNode = new Node();
|
|
|
newNode.Next = null;//插入的为尾部,故其next指向必定为空
|
|
|
|
|
|
newNode.data.fileName = fileName;
|
|
|
newNode.data.SafeFileName = SafeFileName;
|
|
|
newNode.data.fileStartTime = fileStartTime;
|
|
|
newNode.data.fileEndTime = fileEndTime;
|
|
|
newNode.data.fileHead = file_head;
|
|
|
|
|
|
|
|
|
if (_head == null) //如果头节点为空,则链表为空,
|
|
|
{
|
|
|
_head = newNode; //_head直接指向新建的节点。
|
|
|
_head.Pre = null; //而新建的节点的前向引用为null
|
|
|
|
|
|
}
|
|
|
else
|
|
|
{
|
|
|
_end.Next = newNode;
|
|
|
newNode.Pre = _end; //做一次握手。
|
|
|
|
|
|
}
|
|
|
_end = newNode; //插入的位置为链表尾部
|
|
|
_length++; //插入操作,链表长度加一
|
|
|
}
|
|
|
public void Add(string fileName, string SafeFileName, DateTime fileStartTime, DateTime fileEndTime, HEADInfo file_head, byte transtimeOK)
|
|
|
{
|
|
|
//新建一节点
|
|
|
Node newNode = new Node();
|
|
|
newNode.Next = null;//插入的为尾部,故其next指向必定为空
|
|
|
|
|
|
newNode.data.fileName = fileName;
|
|
|
newNode.data.SafeFileName = SafeFileName;
|
|
|
newNode.data.fileStartTime = fileStartTime;
|
|
|
newNode.data.fileEndTime = fileEndTime;
|
|
|
newNode.data.fileHead = file_head;
|
|
|
newNode.data.transtimeOK = transtimeOK;
|
|
|
|
|
|
if (_head == null) //如果头节点为空,则链表为空,
|
|
|
{
|
|
|
_head = newNode; //_head直接指向新建的节点。
|
|
|
_head.Pre = null; //而新建的节点的前向引用为null
|
|
|
|
|
|
}
|
|
|
else
|
|
|
{
|
|
|
_end.Next = newNode;
|
|
|
newNode.Pre = _end; //做一次握手。
|
|
|
|
|
|
}
|
|
|
_end = newNode; //插入的位置为链表尾部
|
|
|
_length++; //插入操作,链表长度加一
|
|
|
}
|
|
|
|
|
|
/// <summary>
|
|
|
/// 把T类型的data装入链表,位置在链表的最后端
|
|
|
/// </summary>
|
|
|
/// <param name="data"></param>
|
|
|
/// <returns></returns>
|
|
|
public void Add(SiteParameter data)
|
|
|
{
|
|
|
//新建一节点
|
|
|
Node newNode = new Node();
|
|
|
newNode.Next = null;//插入的为尾部,故其next指向必定为空
|
|
|
newNode.data = data;
|
|
|
if (_head == null) //如果头节点为空,则链表为空,
|
|
|
{
|
|
|
_head = newNode; //_head直接指向新建的节点。
|
|
|
_head.Pre = null; //而新建的节点的前向引用为null
|
|
|
|
|
|
}
|
|
|
else
|
|
|
{
|
|
|
_end.Next = newNode;
|
|
|
newNode.Pre = _end; //做一次握手。
|
|
|
|
|
|
}
|
|
|
_end = newNode; //插入的位置为链表尾部
|
|
|
_length++; //插入操作,链表长度加一
|
|
|
}
|
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
/// 移除指定位置的元素
|
|
|
/// </summary>
|
|
|
/// <param name="index"></param>
|
|
|
public void RemoveAt(int index)
|
|
|
{
|
|
|
//越界的exception已经在FindNodeByIndex中处理了。
|
|
|
Node flag = FindNodeByIndex(index);
|
|
|
//flag现在已经在要删除的节点处。
|
|
|
|
|
|
if (_head.Next == null)//只有一个节点,且index没有越界即删除的是_head
|
|
|
{
|
|
|
//直接赋空
|
|
|
_head = null;
|
|
|
_end = null;
|
|
|
//这里必须得独立处理,因为 flag.Next.Pre = flag.Pre;
|
|
|
//_head.Next如果为空就不能有Pre指向
|
|
|
}
|
|
|
else//有多于一的节点,且index没有越界,经画图发现可以统一操作。
|
|
|
{
|
|
|
//删除节点操作。。
|
|
|
if (index == _length - 1) _end = _end.Pre;
|
|
|
else flag.Next.Pre = flag.Pre;
|
|
|
if (index == 0) _head = flag.Next;
|
|
|
else flag.Pre.Next = flag.Next;
|
|
|
}
|
|
|
_length--;//非空链表,并且长度没有越界,故长度在删除之后,必然减一
|
|
|
//增加一个字段,就必须要保持一致性。
|
|
|
}
|
|
|
public SiteParameter GetnodeData(int position)
|
|
|
{
|
|
|
Node flag = FindNodeByIndex(position - 1);//从1开始
|
|
|
return flag.data;
|
|
|
|
|
|
}
|
|
|
public void SetNodeData(int position, ref SiteParameter data)
|
|
|
{
|
|
|
Node flag = FindNodeByIndex(position - 1);//从1开始
|
|
|
flag.data = data;
|
|
|
}
|
|
|
|
|
|
/// <summary>
|
|
|
/// 获得索引SiteParameter里边的值
|
|
|
/// </summary>
|
|
|
/// <param name="index"></param>
|
|
|
/// <returns></returns>
|
|
|
public SiteParameter this[int index]
|
|
|
{
|
|
|
get
|
|
|
{
|
|
|
Node flag = FindNodeByIndex(index);
|
|
|
return flag.data;
|
|
|
}
|
|
|
set
|
|
|
{
|
|
|
Node flag = FindNodeByIndex(index);
|
|
|
flag.data = value;
|
|
|
}
|
|
|
}
|
|
|
|
|
|
/// <summary>
|
|
|
/// 清空链表
|
|
|
/// </summary>
|
|
|
public void Clear()
|
|
|
{
|
|
|
_head = null;
|
|
|
_end = null;
|
|
|
_length = 0;
|
|
|
}
|
|
|
|
|
|
/// <summary>
|
|
|
/// 获取链表元素的个数
|
|
|
/// </summary>
|
|
|
public int GetLength()
|
|
|
{
|
|
|
return _length;
|
|
|
}
|
|
|
}
|
|
|
}
|