单链表
单链表(Singly Linked List),也称单向链表,链表中的一种,其特点链接方向是意向的,对链表的访问要通过顺序读取。在顺序链表中元素之间紧密相连,为了表示两个数据元素逻辑上的相邻关系,除了存储数据元素本身的信息外,还要存储与其相邻的下一数据元素的存储地址信息,也就是指针信息,也叫引用域。数据元素信息和指针信息组成该数据元素的存储映像,这就是节点(Node)。
数据域也可使用data表示,指针域使用next表示。
这样线性表就通过每个结点的指针域形成了一根“链条”,也就是我们所说的“链表”。如果结点的引用域只存储该节点直接后继节点的指针域,则该链表称为单链表(Singly Linked List)。单链表结构如下图(图片来自wikipedia):
单链表:
1、末端节点的指针域为空,表示链表的结束;
2、元素间的物理关系是松散的;
3、每一节点存储实际数据,及下一节点的指针,来实现逻辑上的关联。
若末端节点的指针指向头节点,则此链表形成环状,称为单向循环链表(Circularly Linked List);此时的终端节点也就失去了其意义。
单链表实现
1、节点定义:
节点类图如下
代码
/// <summary>
/// 节点定义
/// </summary>
public class Node<T>
{
private T data;//数据域
private Node<T> next;//引用域
/// <summary>
/// 构造器,数据值为输入数据值
/// </summary>
/// <param name="val"></param>
public Node(T val)
{
data = val;
next = null;
}
/// <summary>
/// 构造器,数据值为系统默认值
/// </summary>
public Node()
{
data = default(T);
next = null;
}
/// <summary>
/// 数据域属性
/// </summary>
public T Data
{
get {return data;}
set { data = value; }
}
/// <summary>
/// 引用域属性
/// </summary>
public Node<T> Next
{
get { return next; }
set { next = value; }
}
}
2、单链表实现
单链表类图如下:
代码如下:
代码
/// <summary>
/// 单链表实现
/// </summary>
public class SinglyLinkedList<T>:IListDS<T>
{
private Node<T> head;
/// <summary>
/// 单链表的头节点
/// </summary>
public Node<T> Head
{
get { return head; }
set { head = value; }
}
/// <summary>
/// 构造器,构造具有空指针的头节点
/// </summary>
public SinglyLinkedList()
{
head = null;
}
/// <summary>
/// 求单链表长度
/// </summary>
/// <returns></returns>
public int GetLength()
{
Node<T> currNode = head;
int length = 0;
while (currNode != null)
{
++length;
currNode = currNode.Next;
}
return length;
}
/// <summary>
/// 清空单链表
/// </summary>
public void Clear()
{
head = null;
}
/// <summary>
/// 判断单链表是否为空
/// </summary>
/// <returns></returns>
public bool IsEmpty()
{
return (head == null) ? true : false;
}
/// <summary>
/// 在单链表末尾添加新元素
/// </summary>
/// <param name="item"></param>
public void Append(T item)
{
Node<T> newNode = new Node<T>(item);
Node<T> currNode = null;
if (head == null)
{
head = newNode;
return;
}
currNode = head;
while (currNode.Next != null)
{
currNode = currNode.Next;
}
currNode.Next = newNode;
}
/// <summary>
/// 在指定位置插入元素
/// </summary>
/// <param name="item"></param>
/// <param name="pos"></param>
/// <returns></returns>
public bool Insert(T item, int pos)
{
if (IsEmpty() || pos < 0)
{
Console.WriteLine("The list is empty");
return false;
}
Node<T> newNode = new Node<T>(item);
if (pos == 0)
{
newNode.Next = head;
head = newNode;
return true;
}
Node<T> currNode = head.Next;
Node<T> preNode = head;
int index = 1;
while (currNode.Next != null && index < pos)
{
preNode = currNode;
currNode = currNode.Next;
++index;
}
if (index == pos)
{
newNode.Next = currNode;
preNode.Next = newNode;
return true;
}
else
{
Console.WriteLine("The position is error");
return false;
}
}
/// <summary>
/// 删除指定索引位置的元素
/// </summary>
/// <param name="pos"></param>
/// <returns></returns>
public T Delete(int pos)
{
if (IsEmpty() || pos < 0)
{
Console.WriteLine("The Link is empty");
return default(T);
}
T data = default(T);
if (pos == 0)
{
data = head.Data;
head = head.Next;
return data;
}
Node<T> preNode = this.head;
Node<T> currNode = this.head.Next;
int index = 1;
while (currNode.Next != null && index < pos)
{
++index;
preNode = currNode;
currNode = currNode.Next;
}
if (index == pos)
{
preNode.Next = currNode.Next;
return currNode.Data;
}
else
{
Console.WriteLine("The position is out of range");
return default(T);
}
}
/// <summary>
/// 根据索引查找
/// </summary>
/// <param name="pos"></param>
/// <returns></returns>
public T GetElem(int pos)
{
if (IsEmpty())
{
Console.WriteLine("The list is empty");
return default(T);
}
Node<T> currNode = head;
int index = 0;
while (currNode.Next != null && index < pos)
{
++index;
currNode = currNode.Next;
}
if (index == pos)
return currNode.Data;
else
{
Console.WriteLine("The position is out of range");
return default(T);
}
}
/// <summary>
/// 根据值查找
/// </summary>
/// <param name="value"></param>
/// <returns></returns>
public int Locate(T value)
{
if (IsEmpty())
{
Console.WriteLine("The list is empty");
return -1;
}
Node<T> currNode = new Node<T>();
currNode = head;
int pos = -1;
while (currNode != null && currNode.Data.Equals(value))
{
currNode = currNode.Next;
++pos;
}
if (currNode == null)
return -1;
return pos;
}
}
调用演示:
代码
/// <summary>
/// 功能:单链表演示
/// 开发:walkingp
/// 时间:2010-4-29
/// 主页:http://www.51obj.cn/
/// </summary>
class Program
{
static void Main(string[] args)
{
SinglyLinkedList<string> demoList = new SinglyLinkedList<string>();
/*添加*/
demoList.Append("Wang Hongjian");
demoList.Append("ZhangSan");
demoList.Append("LiSi");
for (int i = 0; i < demoList.GetLength(); i++)
{
Console.WriteLine("The {0} item is:\t{1}",i, demoList.GetElem(i));
}
/*插入*/
Console.WriteLine("Insert the item:");
demoList.Insert("Zhangyu", 1);
for (int i = 0; i < demoList.GetLength(); i++)
{
Console.WriteLine("The {0} item is:\t{1}", i, demoList.GetElem(i));
}
/*删除*/
Console.WriteLine("Delelte the item:");
demoList.Delete(3);
for (int i = 0; i < demoList.GetLength(); i++)
{
Console.WriteLine("The {0} item is:\t{1}", i, demoList.GetElem(i));
}
/*根据索引查找*/
Console.WriteLine("The 2st item is:\t{0}", demoList.GetElem(1));
/*根据值查找*/
Console.WriteLine("The position of the item 'Wang Hongjian' is:\t{0}",demoList.Locate("Wang Hongjian"));
/*清空*/
demoList.Clear();
Console.WriteLine("Now the list is empty");
}
演示效果:
========================================================
C#数据结构系列文章:
1、基础知识
4、双向链表Double Linked List
5、循环链表Circular Linked List
6、栈Stack
7、队列Queue
8、串
9、数组Array
10、树Tree
...
我的主页:http://www.51obj.cn/