对于阅读本文的那些从未创建过线性链表的人。你可以将线性链表想像成有一条链子栓在一起的盒子(称作一个结点),每个盒子里包含着一些数据 和 链接到这个链子上的下一个盒子的引用(当然,除了最后一个盒子,这个盒子对于下一个盒子的引用被设置成NULL)。
为了创建我们的简单线性链表,我们需要下面三个类:
1、Node 类,包含数据以及下一个Node的引用。
2、LinkedList 类,包含链表中的第一个Node,以及关于链表的任何附加信息。
3、测试程序,用于测试 LinkedList 类。
为了查看链接表如何运作,我们添加Objects的两种类型到链表中:整型 和 Employee类型。你可以将Employee类型想象成一个包含关于公司中某一个员工所有信息的类。出于演示的目的,Employee类非常的简单。
- public class Employee{
- private string name;
- public Employee (string name){
- this.name = name;
- }
- public override string ToString(){
- return this.name;
- }
- }
这个类仅包含一个表示员工名字的字符串类型,一个设置员工名字的构造函数,一个返回Employee名字的ToString()方法。
链接表本身是由很多的Node构成,这些Note,如上面所说,必须包含数据(整型 和 Employee)和链表中下一个Node的引用。
- public class Node{
- Object data;
- Node next;
- public Node(Object data){
- this.data = data;
- this.next = null;
- }
- public Object Data{
- get { return this.data; }
- set { data = value; }
- }
- public Node Next{
- get { return this.next; }
- set { this.next = value; }
- }
- }
注意构造函数将私有的数据成员设置成传递进来的对象,并且将 next 字段设置成null。
这个类还包括一个方法,Append,这个方法接受一个Node类型的参数,我们将把传递进来的Node添加到列表中的最后位置。这过程是这样的:首先检测当前Node的next字段,看它是不是null。如果是,那么当前Node就是最后一个Node,我们将当前Node的next属性指向传递进来的新结点,这样,我们就把新Node插入到了链表的尾部。
如果当前Node的next字段不是null,说明当前node不是链表中的最后一个node。因为next字段的类型也是node,所以我们调用next字段的Append方法(注:递归调用),再一次传递Node参数,这样继续下去,直到找到最后一个Node为止。
- public void Append(Node newNode){
- if ( this.next == null ){
- this.next = newNode;
- }else{
- next.Append(newNode);
- }
- }
Node 类中的 ToString() 方法也被覆盖了,用于输出 data 中的值,并且调用下一个 Node 的 ToString()方法(译注:再一次递归调用)。
- public override string ToString(){
- string output = data.ToString();
- if ( next != null ){
- output += ", " + next.ToString();
- }
- return output;
- }
这样,当你调用第一个Node的ToString()方法时,将打印出所有链表上Node的值。
LinkedList 类本身只包含对一个Node的引用,这个Node称作 HeadNode,是链表中的第一个Node,初始化为null。
- public class LinkedList{
- Node headNode = null;
- }
LinkedList 类不需要构造函数(使用编译器创建的默认构造函数),但是我们需要创建一个公共方法,Add(),这个方法把 data存储到线性链表中。这个方法首先检查headNode是不是null,如果是,它将使用data创建结点,并将这个结点作为headNode,如果不是null,它将创建一个新的包含data的结点,并调用headNode的Append方法,如下面的代码所示:
- public void Add(Object data){
- if ( headNode == null ){
- headNode = new Node(data);
- }else{
- headNode.Append(new Node(data));
- }
- }
为了提供一点集合的感觉,我们为线性链表创建一个索引器。
- public object this[ int index ]{
- get{
- int ctr = 0;
- Node node = headNode;
- while ( node != null && ctr < = index ){
- if ( ctr == index ){
- return node.Data;
- }else{
- node = node.Next;
- }
- ctr++;
- }
- return null;
- }
- }
最后,ToString()方法再一次被覆盖,用以调用headNode的ToString()方法。
- public override string ToString(){
- if ( this.headNode != null ){
- return this.headNode.ToString();
- }else{
- return string.Empty;
- }
- }
这样,一个线性链表就创建好了。
【编辑推荐】