单向链表:
学习目标:
- 掌握什么是单向链表
- 单向链表的实际运用
- C#中如何实现单向链表
学习内容:
- 了解何为单向链表
- 了解单向链表的优缺点
- 了解单向链表在实际开发中的应用
- 掌握用C#实现单向链表
何为单向链表:
链表是一种物理存储结构上非连续、非顺序的存储结构,数据元素的逻辑顺序是通过链表中的指针链接次序实现的。链表由一系列结点(链表中每一个元素称为结点)组成,结点可以在运行时动态生成。每个结点包括两个部分:一个是存储数据元素的数据域,另一个是存储下一个结点地址的指针域。
单向链表的优缺点:
优点:
- 插入和删除速度快,保留原有的物理顺序,在插入或者删除一个元素的时候,只需要改变指针指向即可。
- 没有空间限制,存储元素无上限,只与内存空间大小有关。
- 动态分配内存空间,不用事先开辟内存
缺点:
- 占用额外的空间以存储指针,比较浪费空间,不连续存储,malloc函数开辟空间碎片比较多
- 查找速度比较慢,因为在查找时,只能顺序查找,需要循环链表
单向链表在实际开发中的应用
例如展示职工信息的时候,按照编号进行递增排序,或者在某些数据进行在后台处理进行排序的时候可以使用链表,例如名次排列,成绩排列等。
C# 实现单向链表:
interface Queue<T>
{
int getSize();
bool isEmpty();
void enqueue(T data);
T dequeue();
/// <summary>
/// 查看栈顶元素
/// </summary>
/// <returns></returns>
T getFront();
}
public class LinkedListQueue<T> : Queue<T>
{
public class Node
{
public T data;
public Node next;
public Node(T data, Node next)
{
this.data = data;
this.next = next;
}
public Node(T data) : this(data, null)
{
}
public Node() : this(default(T), null)
{
}
public override string ToString()
{
return data.ToString();
}
}
public Node head, tail;
private int size;
public LinkedListQueue()
{
head = null;
tail = null;
size = 0;
}
public T dequeue()
{
if (isEmpty())
{
throw new System.Exception("size is 0 no dequue");
}
Node node = head;
head = node.next;
node.next = null;
if (head == null)
{
tail = null;
}
size--;
return node.data;
}
public void enqueue(T data)
{
//如果头是空的情况下 tail 才是空的
if (tail == null)
{
tail = new Node(data);
head = tail;
}
else
{
tail.next = new Node(data);
this.tail = tail.next;
}
size++;
}
public T getFront()
{
if (isEmpty())
{
throw new System.Exception("size is 0 no dequue");
}
return head.data;
}
public int getSize()
{
return size;
}
public bool isEmpty()
{
return size == 0;
}
public override string ToString()
{
System.Text.StringBuilder stringBuilder = new System.Text.StringBuilder();
stringBuilder.Append("queue : front");
Node cur = head;
while (cur != null)
{
stringBuilder.Append(cur + "->");
cur = cur.next;
}
stringBuilder.Append("Null tail");
return stringBuilder.ToString();
}
}
interface Stack<T>
{
int getSize();
bool isEmpty();
void push(T data);
T pop();
/// <summary>
/// 查看栈顶元素
/// </summary>
/// <returns></returns>
T peek();
}
public class LinkedListStack<T> : Stack<T>
{
private LinkedList<T> list;
public LinkedListStack()
{
list = new LinkedList<T>();
}
public int getSize()
{
return list.getSize();
}
public bool isEmpty()
{
return list.getSize() == 0;
}
public T peek()
{
return list.getFirst();
}
public T pop()
{
return list.removeFirst();
}
public void push(T data)
{
list.addFirst(data);
}
public override string ToString()
{
System.Text.StringBuilder stringBuilder = new System.Text.StringBuilder();
stringBuilder.Append(" stack :top");
stringBuilder.Append(list);
return stringBuilder.ToString();
}
}
public class LinkedList<T>
{
private class Node
{
public T data;
public Node next;
public Node(T data, Node next)
{
this.data = data;
this.next = next;
}
public Node(T data) : this(data, null)
{
}
public Node() : this(default(T), null)
{
}
public override string ToString()
{
return data.ToString();
}
}
// private Node head = null;
/// <summary>
/// 虚拟头结点
/// </summary>
private Node dummyHead = null;
private int size;
public LinkedList()
{
// head = null;
dummyHead = new Node();
size = 0;
}
public int getSize()
{
return size;
}
public bool usEmpty()
{
return size == 0;
}
public void addFirst(T data)
{
Add(data, 0);
}
public void Add(T data, int index)
{
if (index < 0 || index > size)
throw new System.Exception("add failed,allegal index");
Node prev = dummyHead;
for (var i = 0; i < index; i++)
{
prev = prev.next;
}
// System.Console.WriteLine(data);
prev.next = new Node(data, prev.next);
size++;
}
public void AddLast(T data)
{
Add(data, size);
}
public T get(int index)
{
if (index < 0 || index >= size)
throw new System.Exception("get failed illegal index.");
Node curr = dummyHead.next;
for (var i = 0; i < index; i++)
{
curr = curr.next;
}
return curr.data;
}
public T getFirst()
{
return get(0);
}
public T getLast()
{
return get(size - 1);
}
public void Set(int index, T data)
{
if (index < 0 || index >= size)
throw new System.Exception("set failed illegal index.");
Node curr = dummyHead.next;
for (var i = 0; i < index; i++)
{
curr = curr.next;
}
curr.data = data;
}
public bool contains(T data)
{
Node curr = dummyHead.next;
while (curr != null)
{
if (curr.data.Equals(data))
{
return true;
}
}
return false;
}
public override string ToString()
{
System.Text.StringBuilder stringBuilder = new System.Text.StringBuilder();
Node curr = dummyHead.next;
while (curr != null)
{
stringBuilder.Append(curr + "=>");
curr = curr.next;
}
stringBuilder.Append("NULL");
return stringBuilder.ToString();
}
public T Remove(int index)
{
Node prev = dummyHead;
for (var i = 0; i < index; i++)
{
prev = prev.next;
}
Node node = prev.next;
prev.next = node.next;
node.next = null;
size--;
return node.data;
}
public T removeFirst()
{
return Remove(0);
}
public T removeLast()
{
return Remove(size - 1);
}
}