using System; using System.Collections.Generic; using System.Text; using System.Net; using System.Net.Sockets; namespace Dat2Bin { public class LinkList { /// /// 链表长度 /// 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; } } /// /// 查找索引值index个链表节点。 /// /// /// /// 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; } /// /// 把T类型的data装入链表,位置在链表的最后端 /// /// /// 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++; //插入操作,链表长度加一 } /// /// 把T类型的data装入链表,位置在链表的最后端 /// /// /// 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++; //插入操作,链表长度加一 } /// /// 移除指定位置的元素 /// /// 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; } /// /// 获得索引SiteParameter里边的值 /// /// /// public SiteParameter this[int index] { get { Node flag = FindNodeByIndex(index); return flag.data; } set { Node flag = FindNodeByIndex(index); flag.data = value; } } /// /// 清空链表 /// public void Clear() { _head = null; _end = null; _length = 0; } /// /// 获取链表元素的个数 /// public int GetLength() { return _length; } } }