/// <summary> /// 判断一个结点是否属于当前的环形链表[属于返回true,不属于则返回false] /// </summary> /// <param name="node">结点</param> /// <returns>属于返回true,不属于则返回false</returns> private bool ExistNode(LoopLinkedNode <T> node) { //如果没有节点就直接返回 if (this._firstNode == null) { return(false); } //如果只有一个节点,就直接判断 if (this._items.Count == 1) { return(this._firstNode == node); } bool result = false; //当有两个以上的节点果则二分查找 var pp = this._firstNode.Previous; //上一个 var pn = this._firstNode; //下一个 while (true) { if (pp == pn) { if (pp == node) { result = true; } break; } if (pp == node) { result = true; break; } if (pn == node) { result = true; break; } if (pn.Next == pp) { if (pp == node) { result = true; } break; } pp = pp.Previous; pn = pn.Next; } return(result); }
/// <summary> /// 在指定节点之前添加新节点 /// </summary> /// <param name="node">指定的节点</param> /// <param name="item">新项</param> public void AddBefore(LoopLinkedNode <T> node, T item) { var newNode = new LoopLinkedNode <T>(item); node.Previous.Next = newNode; newNode.Previous = node.Previous; newNode.Next = node; node.Previous = newNode; this._items.Add(item); }
/// <summary> /// 删除一个指定的节点 /// </summary> /// <param name="node">要删除的节点</param> private void DeleteNode(LoopLinkedNode <T> node) { //如果删除的是第一个节点,就把先把第二节点设置为第一个节点 if (this._firstNode == node) { this._firstNode = this._firstNode.Next; } node.Previous.Next = node.Next; node.Next.Previous = node.Previous; this._items.Remove(node.Value); }
/// <summary> /// 移除一项 /// </summary> /// <param name="node">要移除的项</param> public void Remove(LoopLinkedNode <T> node) { if (node == null) { throw new ArgumentNullException(nameof(node)); } if (this.ExistNode(node)) { this.DeleteNode(node); } else { throw new ArgumentException("结点不属于当前环形链表"); } }
/// <summary> /// 定时操作 /// </summary> /// <param name="para">线程参数</param> private void TimingThreadMethod(ThreadExPara para) { LoopLinked <AlarmTime> alarmLoopLinked = this.CreateAlarmLoopLinked(); if (alarmLoopLinked.Count == 0) { throw new Exception("没有添加时间点"); } // 当前执行次数 int excuteCount = 0; LoopLinkedNode <AlarmTime> currentNode = alarmLoopLinked.FirstNode; TimeSpan tsWait; while (true) { tsWait = this.CaculateWaitTime(currentNode.Value.Time); //如果停止门铃执行 if (para.Token.IsCancellationRequested) { break; } Thread.Sleep(tsWait); //如果停止门铃执行 if (para.Token.IsCancellationRequested) { break; } //响铃 this.OnRing(currentNode.Value.Time); //执行次数验证,如果不为无限次,那么当执行的次数超过要执行的总次数时,就停止 if (this._count != -1) { excuteCount++; if (excuteCount >= this._count) { break; } } currentNode = currentNode.Next; } }
/// <summary> /// 在纯属处添加新节点 /// </summary> /// <param name="item">新项</param> public void AddLast(T item) { if (this._firstNode == null) { this._firstNode = new LoopLinkedNode <T>(item); this._firstNode.Next = this._firstNode; this._firstNode.Previous = this._firstNode; } else { var newNode = new LoopLinkedNode <T>(item); newNode.Previous = this._firstNode.Previous; this._firstNode.Previous.Next = newNode; newNode.Next = this._firstNode; this._firstNode.Previous = newNode; } this._items.Add(item); }
/// <summary> /// 构造函数 /// </summary> /// <param name="value">数据项</param> /// <param name="pre">上一个节点</param> /// <param name="next">下一个节点</param> internal LoopLinkedNode(T value, LoopLinkedNode <T> pre, LoopLinkedNode <T> next) : this(value) { this.Previous = pre; this.Next = next; }
/// <summary> /// 查找数据项所在节点 /// </summary> /// <param name="item">数据项</param> /// <returns>找到返回该项所在节点,没找到返回null</returns> public LoopLinkedNode <T> Find(T item) { //如果没有节点就直接返回 if (this._firstNode == null) { return(null); } //如果只有一个节点,就直接判断 if (this._items.Count == 1) { if (this._firstNode.Value.Equals(item)) { return(this._firstNode); } else { return(null); } } LoopLinkedNode <T> result = null; //当有两个以上的节点果则二分查找 var pp = this._firstNode.Previous; //上一个 var pn = this._firstNode; //下一个 while (true) { if (pp == pn) { if (pp.Value.Equals(item)) { result = pp; } break; } if (pp.Value.Equals(item)) { result = pp; break; } if (pn.Value.Equals(item)) { result = pn; break; } if (pn.Next == pp) { if (pp.Value.Equals(item)) { result = pp; } break; } pp = pp.Previous; pn = pn.Next; } return(result); }