C# 作为泛型的可空类型
我正在尝试为我的个人库创建一个可以处理所有事情的链接列表。我正试图编写它,以便它可以“同样”轻松地手动C# 作为泛型的可空类型,c#,linked-list,C#,Linked List,我正在尝试为我的个人库创建一个可以处理所有事情的链接列表。我正试图编写它,以便它可以“同样”轻松地手动int,null,DateTime或Class,并且我希望它可以轻松地扩展,这样,如果我想快速地从中生成堆栈,我就可以编写push,pop,和peek方法等等 目前,我的代码如下所示。请注意,我使用“Base”作为泛型类型 namespace ClassLibrary1 { public class LinkedList<Base> where Base : class
int
,null
,DateTime
或Class
,并且我希望它可以轻松地扩展,这样,如果我想快速地从中生成堆栈,我就可以编写push
,pop
,和peek
方法等等
目前,我的代码如下所示。请注意,我使用“Base”作为泛型类型
namespace ClassLibrary1
{
public class LinkedList<Base> where Base : class
{
public class Node
{
private Node next;
private Node prev;
private Base value;
/// <summary>
/// Constructor for Nodes of Circular Linked List class.
/// Calls overloaded constructor for no previous or next provided.
/// O(1)
/// </summary>
/// <param name="value">The value to be stored. Can use tuple for associations</param>
public Node(Base value)
{
new Node(null, null, value);
}
/// <summary>
/// Constructor for nodes of Circular Linked List class.
/// O(1)
/// </summary>
/// <param name="prev">The previous node in the linked list</param>
/// <param name="next">The next node in the linked list</param>
/// <param name="value">The value to be stored</param>
public Node(Node prev, Node next, Base value)
{
this.prev = prev;
this.next = next;
this.value = value;
}
/// <summary>
/// Sets the 'next' attribute of the node to the passed value.
/// O(1)
/// Chainable
/// </summary>
/// <param name="next">The new value of the 'next' attribute.</param>
/// <returns>Chainable(Node, this)</returns>
public Node setNext(Node next)
{
this.next = next;
return this;
}
/// <summary>
/// Sets the 'prev' attribute of the node to the passed value
/// O(1)
/// Chainable
/// </summary>
/// <param name="prev">The new value of the 'prev' attribute to denote the previous node</param>
/// <returns>Chainable(Node, this)</returns>
public Node setPrev(Node prev)
{
this.prev = prev;
return this;
}
/// <summary>
/// Changes the stored value of type Base to the passed value.
/// O(1)
/// Chainable
/// </summary>
/// <param name="value">The new value to be stored with the node</param>
/// <returns>Chainable(Node, this)</returns>
public Node setVal(Base value)
{
this.value = value;
return this;
}
/// <summary>
/// Returns the next node in the linked list.
/// O(1)
/// </summary>
/// <returns>The next node in the linked list.(Node)</returns>
public Node getNext()
{
return this.next;
}
/// <summary>
/// Returns the previous node in the linked list.
/// O(1)
/// </summary>
/// <returns>The previous node in the linked list.(Node)</returns>
public Node getPrev()
{
return this.prev;
}
/// <summary>
/// Returns the value stored at this node.
/// O(1)
/// </summary>
/// <returns>The value stored at this node.(Base)</returns>
public Base getVal()
{
return this.value;
}
}
public Node head;
public bool duplicates;
public bool hasNullValues;
public bool throwNullError;
/// <summary>
/// Constructor for the LinkedList. Creates a null head node.
/// Duplication defaulted to false
/// O(1)
/// </summary>
public LinkedList()
{
this.head = new Node(null);
this.head.setNext(this.head).setPrev(this.head);
this.duplicates = false;
this.hasNullValues = false;
this.throwNullError = false;
}
/// <summary>
/// Allows duplication for the linked list.
/// O(1)
/// Chainable attribute.
/// </summary>
/// <returns>Chainable.(LinkedList<Base>, this)</returns>
public LinkedList<Base> hasDuplicates()
{
this.duplicates = true;
return this;
}
/// <summary>
/// Allows the structure to store null values in nodes.
/// O(1)
/// Chainable.
/// </summary>
/// <returns>Chainable.(LinkedList<Base>, this)</returns>
public LinkedList<Base> hasNulls()
{
this.hasNullValues = true;
return this;
}
/// <summary>
/// Causes the structure to throw a null error when a null value is inserted.
/// If hasNulls is off, turns it on.
/// O(1)
/// Chainable.
/// </summary>
/// <returns>Chainable.(LinkedList<Base>, this)</returns>
public LinkedList<Base> throwsNulls()
{
if (!this.hasNullValues)
{
this.hasNullValues = true;
}
this.throwNullError = true;
return this;
}
/// <summary>
/// Iff duplicates not allowed, searches for value in list. Throws error if duplicate found.
/// Creates a new node at the end of the list, then links it to the head node.
/// O(length) [if hasDuplicates()]
/// O(1) [if else]
/// Chainable
/// </summary>
/// <param name="value">Value stored at the new node in the list</param>
/// <returns>Chainable.(LinkedList<Base>, this)</returns>
public LinkedList<Base> add(Base value)
{
if (!duplicates)
{
if (search(value) != null)
{
throw new Exception("Value already exists in the linked list.");
}
}
if (!this.hasNullValues && value != null)
{
if (this.throwNullError)
{
throw new Exception("Cannot insert null values");
}
else
{
return this;
}
}
Node newNode = new Node(value);
this.head.getPrev().setNext(newNode);
this.head.setPrev(newNode);
return this;
}
/// <summary>
/// Iterates through the list until first such node for with a matching value is found.
/// Returns null if no matches found.
/// Use searchAll to find duplicates.
/// O(length)
/// </summary>
/// <param name="value">The value to be searched for.</param>
/// <returns>First node with the desired value(Node?)</returns>
public Node search(Base value)
{
Node temp = this.head.getNext();
while (!temp.getVal().Equals(value))
{
if (temp.Equals(this.head))
{
return null;
}
temp = temp.getNext();
}
return temp;
}
/// <summary>
/// If value doesn't exist in the list, throws an exception.
/// Deletes the first node found with the chosen value.
/// Use DeleteAll to delete all instances.
/// Chainable.
/// O(length)
/// </summary>
/// <param name="value">Value to be removed from the list.</param>
/// <returns>Chainable.(LinkedList<Base>, this)</returns>
public LinkedList<Base> delete(Base value)
{
try{
return delete(search(value));
}
catch(Exception e){
throw new Exception("Node to be deleted not found");
}
}
/// <summary>
/// Removes all pointers to the passed node.
/// O(1)
/// </summary>
/// <param name="tbd">The node to be deleted.</param>
/// <returns>Chainable.(LinkedList<Base>, this)</returns>
public LinkedList<Base> delete(Node tbd)
{
if (tbd.Equals(this.head))
{
throw new Exception("Cannot delete head node");
}
else
{
tbd.getPrev().setNext(tbd.getNext());
tbd.getNext().setPrev(tbd.getPrev());
}
return this;
}
/// <summary>
/// Returns a LinkedList of all nodes containing the desired value.
/// O(length)
/// </summary>
/// <param name="value">The value to be found.</param>
/// <returns>A LinkedList of Nodes with matching values.(LinkedList<Node>)</returns>
public LinkedList<Node> searchAll(Base value)
{
LinkedList<Node> returnList = new LinkedList<Node>();
Node temp = this.head.getNext();
while (!temp.Equals(this.head))
{
if (temp.getVal().Equals(value))
{
returnList.add(temp);
}
temp = temp.getNext();
}
return returnList;
}
/// <summary>
/// Returns the first Node in the Linked List.
/// O()
/// </summary>
/// <returns>First non-head node in the list.(Node)</returns>
public Node firstOrDefault()
{
return this.head.getNext();
}
/// <summary>
/// Returns the value of the first node in the list.
/// O(1)
/// </summary>
/// <returns>FIrst non-head </returns>
public Base firstVal()
{
return this.head.getNext().getVal();
}
/// <summary>
/// Gets the last node in the linked list.
/// O(1)
/// </summary>
/// <returns>The last node in the linked list.(Node)</returns>
public Node tail()
{
return this.head.getPrev();
}
/// <summary>
/// Returns the value of the last node in the linked list.
/// O(1)
/// </summary>
/// <returns>VThe value of the tail node.(Base)</returns>
public Base tailVal()
{
return this.head.getPrev().getVal();
}
public static void Main()
{
LinkedLis t<Int32> mine = new LinkedList<Int32>();
}
}
}
命名空间类库1
{
公共类链接列表,其中基:类
{
公共类节点
{
私有节点下一步;
私有节点prev;
私人基础价值;
///
///循环链表类的节点的构造函数。
///为未提供的上一个或下一个调用重载构造函数。
///O(1)
///
///要存储的值。可以使用元组进行关联
公共节点(基值)
{
新节点(null,null,value);
}
///
///循环链表类的节点的构造函数。
///O(1)
///
///链接列表中的上一个节点
///链接列表中的下一个节点
///要存储的值
公共节点(节点上一个、节点下一个、基值)
{
this.prev=prev;
this.next=next;
这个值=值;
}
///
///将节点的“next”属性设置为传递的值。
///O(1)
///可链接
///
///“下一个”属性的新值。
///可链接(节点,此)
公共节点设置下一步(节点下一步)
{
this.next=next;
归还这个;
}
///
///将节点的“prev”属性设置为传递的值
///O(1)
///可链接
///
///“prev”属性的新值表示上一个节点
///可链接(节点,此)
公共节点setPrev(节点prev)
{
this.prev=prev;
归还这个;
}
///
///将Base类型的存储值更改为传递的值。
///O(1)
///可链接
///
///要与节点一起存储的新值
///可链接(节点,此)
公共节点setVal(基值)
{
这个值=值;
归还这个;
}
///
///返回链接列表中的下一个节点。
///O(1)
///
///链接列表中的下一个节点。(节点)
公共节点getNext()
{
把这个还给我,下一个;
}
///
///返回链接列表中的上一个节点。
///O(1)
///
///链接列表中的上一个节点。(节点)
公共节点getPrev()
{
返回此.prev;
}
///
///返回存储在此节点上的值。
///O(1)
///
///存储在此节点上的值。(基本)
公共基getVal()
{
返回此.value;
}
}
公共节点头;
公共文件副本;
公共价值观;
公共布尔thrownulllerror;
///
///LinkedList的构造函数。创建空头节点。
///复制默认为false
///O(1)
///
公共链接列表()
{
this.head=新节点(空);
this.head.setNext(this.head).setPrev(this.head);
这个。重复=假;
this.hasNullValues=false;
this.throwNullError=false;
}
///
///允许复制链接列表。
///O(1)
///可链接属性。
///
///可链接。(链接列表,此)
公共链接列表具有重复项()
{
this.duplicates=true;
归还这个;
}
///
///允许结构在节点中存储空值。
///O(1)
///可链接的。
///
///可链接。(链接列表,此)
公共链接列表hasNulls()
{
this.hasNullValues=true;
归还这个;
}
///
///导致结构在插入空值时抛出空错误。
///如果hasNulls处于禁用状态,则将其打开。
///O(1)
///可链接的。
///
///可链接。(链接列表,此)
公共链接列表throwsNulls()
{
如果(!this.hasNullValues)
{
this.hasNullValues=true;
}
this.throwNullError=true;
归还这个;
}
///
///Iff不允许重复,搜索列表中的值。如果发现重复,则抛出错误。
///在列表末尾创建一个新节点,然后将其链接到头部节点。
///O(长度)[如果有重复项()]
///O(1)[如另有规定]
///可链接
///
///存储在列表中新节点上的值
///可链接。(链接列表,此)
公共链接列表添加(基值)
{
如果(!重复)
{
如果(搜索(值)!=null)
{
抛出新异常(“链接列表中已存在值”);
}
}
如果(!this.hasNullValues&&value!=null)
{
if(this.throwNullError)
{
public class LinkedList<Base> where Base : class
new LinkedList<Int32>()