1. 什么是链表
class LinkedList1<E>
{
private class Node
{
public E e; //实际存储的元素,E类型的泛型,支持任意类型的数组
public Node next; //记录当前节点的下一个节点
public Node(E e,Node next) //用构造函数对这个类进行初始化
{
this.e = e;
this.next = next;
}
public Node(E e) //用户不知道下一个节点是什么
{
this.e = e;
this.next = null; //这个节点没有下一个节点
}
public override string ToString()
{
return e.ToString();
}
}
private Node head; //记录链表的头部
private int N; //记录链表存储了多少元素
public LinkedList1()
{
head = null;
N = 0;
}
//链表不具备容量概念,有多少元素就创建多少个节点,没有容量的限制
//存储数量
public int Count
{
get { return N; }
}
//判断是否为空
public bool IsEmpty
{
get { return N == 0; }
}
}
2.往链表添加节点
//添加
public void Add(int index, E e)
{
if (index < 0 || index > N)
{
throw new ArgumentException("非法索引!");
}
if (index == 0)
{
Node node = new Node(e);
node.next = head;
head = node;
//此处也可以用一行代码:
//head = new Node(e, head);
}
else
{
Node pre = head; //从头部开始查找(要插入节点的前一个)节点
for (int i = 0; i < index - 1; i++)
//因为要在index位置插入新节点,所以要找到index位置前一个节点
pre = pre.next;
Node node = new Node(e);
node.next = pre.next;
pre.next = node;
//此处也可以用一行代码:
//pre.next = new Node(e, pre.next);
}
N++;
}
public void AddFirst(E e)
{
Add(0, e);
}
public void AddLast(E e)
{
Add(N, e);
}
3.查询、修改、包含、打印
查询:
//查询
public E Get(int index)
{
if (index < 0 || index >= N)
throw new ArgumentException("非法索引!");
Node cur = head;
for (int i = 0; i < index; i++)
cur = cur.next;
return cur.e;
}
public E GetFirst()
{
return Get(0);
}
public E GetLast()
{
return Get(N - 1);
}
修改:
//修改
public void Set(int index, E newE)
{
if (index < 0 || index >= N)
throw new ArgumentException("非法检索!");
Node cur = head;
for (int i = 0; i < index; i++)
cur = cur.next;
cur.e = newE;
}
包含:
//包含
public bool Contains(E e)
{
Node cur = head;
while (cur != null)
{
if (cur.e.Equals(e))
return true;
cur = cur.next;
}
return false;
}
打印:
//打印
public override string ToString()
{
StringBuilder res = new StringBuilder();
Node cur = head;
while (cur!=null)
{
res.Append(cur + " -> ");
cur = cur.next;
}
res.Append("Null");
return res.ToString();
}
4.删除链表中的节点
//删除
public E RemoveAt(int index)
{
if (index < 0 || index >= N)
throw new ArgumentException("非法检索!");
if (index == 0) //删除头部节点
{
Node delNode = head;
head = head.next;
N--;
return delNode.e;
}
else //删除中间或尾部的节点
{
Node pre = head;
for (int i = 0; i < index - 1; i++)
pre = pre.next;
Node delNode = pre.next;
pre.next = delNode.next;
N--;
return delNode.e;
}
}
//删除指定结点
public void Remove(E e)
{
if (head == null)
return;
if (head.e.Equals(e))
{
head = head.next;
N--;
}
else
{
Node cur = head;
Node pre = null;
while (cur != null)
{
if (cur.e.Equals(e)) //遍历过程中发现这个结点就是要找的结点,则退出循环
{
pre.next = cur.next;
break;
}
else
{
pre = cur; //否则给指针进行赋值移动
cur = cur.next;
}
}
N--;
}
}
5.时间复杂度分析