数据结构单链表

    链表是用一组任意的存储单元来存储线性表中的数据元素(这组存储单元可以是连续的,也可以是不连续的)。那么,怎么表示两个数据元素逻辑上的相邻关系呢?即如何表示数据元素之间的线性关系呢?为此,在存储数据元素时,除了存储数据元素本身的信息外,还要存储与它相邻的数据元素的存储地址信息。这两部分信息组成该数据元素的存储映像(Image),称为结点(Node)。把存储据元素本身信息的域叫结点的数据域(Data Domain),把存储与它相邻的数据元素的存储地址信息的域叫结点的引用域(Reference Domain)。因此,线性表通过每个结点的引用域形成了一根“链条”,这就是“链表”名称的由来。
如果结点的引用域只存储该结点直接后继结点的存储地址,则该链表叫单链表(Singly Linked List)。把该引用域叫next。单链表结点的结构如图2.5所示,图中data表示结点的数据域。

2010052108520494.jpg

把单链表结点看作是一个类,类名为Node<T>。单链表结点类的实现如下所示。

 

 

ContractedBlock.gif ExpandedBlockStart.gif 代码
 
   
public class Node < T >
{
private T data; // 数据域
private Node < T > next; // 引用域

// 构造器

public Node(T val, Node < T > p)
{
data
= val;
next
= p;
}

// 构造器
public Node(Node < T > p)
{
next
= p;
}
// 构造器
public Node(T val)
{
data
= val;
next
= null ;
}
// 构造器
public Node()
{
data
= default (T);
next
= null ;
}
// 数据域属性
public T Data
{
get { return data; }
set { data = value; }
}
// 引用域属性
public Node < T > Next
{
get { return next; }
set { next = value; }
}
}

是线性表(a1,a2,a3,a4,a5,a6)对应的链式存储结构示意图。
存储地址 data next 

头引用H 
 2010052108545262.jpg

   通常,我们把链表画成用箭头相连接的结点的序列,结点间的箭头表示引用域中存储的地址。为了处理上的简洁与方便,在本书中把引用域中存储的地址叫引用,如图示

      2010052108580371.jpg

    由图可知,单链表由头引用H唯一确定。头引用指向单链表的第一个结点,也就是把单链表第一个结点的地址放在H中,所以,H是一个Node类型的变量。头引用为null表示一个空表。
把单链表看作是一个类,类名叫LinkList<T>。LinkList<T>类也实现了接口IListDS<T>。LinkList<T>类有一个字段head,表示单链表的头引用,所以head的类型为Node<T>。由于链表的存储空间不是连续的,所以没有最大空间的限制,在链表中插入结点时不需要判断链表是否已满。因此,在LinkList<T>类中不需要实现判断链表是否已满的成员方法。
单链表类LinkList<T>的实现说明如下所示。

 

ContractedBlock.gif ExpandedBlockStart.gif 代码
 
   
public class LinkList < T > :IList < T >
{
private Node < T > head; // 单链表的头引用

// 头引用属性
public Node < T > Head
{
get
{
return head;
}
set
{
head
= value;
}
}
// 构造器
public LinkList()
{
head
= null ;

}
// 链表的基本操作
// 求单链表的长度
public int GetLenght()
{
Node
< T > p = head;

int len = 0 ;
while (p != null )
{
++ len;
p
= p.Next;
}
return len;
}
// 清空单链表
public void Clear()
{
head
= null ;
}
// 判断单链表是否为空
public bool IsEmpty()
{
if (head == null )
{
return true ;
}
else
{
return false ;
}
}
// 在单链表的末尾添加新元素
public void Append(T item)
{
Node
< T > q = new Node < T > (item);
Node
< T > p = new Node < T > ();

if (head == null )
{
head
= q;
return ;

}
p
= head;
while (p.Next != null )
{
p
= p.Next;
}
p.Next
= q;
}
// 在单链表的第i个结点的位置前插入一个值为item的元素
public void Insert(T item, int i)
{
if (IsEmpty() || i < 1 )
{
Console.WriteLine(
" List is empty or Position is error " );
return ;
}

if (i == 1 )
{
Node
< T > q = new Node < T > (item);
q.Next
= head;
head
= q;
return ;
}
Node
< T > p = head;
Node
< T > r = new Node < T > ();
int j = 1 ;

while (p.Next != null && j < i)
{
r
= p;
p
= p.Next;
++ j;
}
if (j == i)
{
Node
< T > q = new Node < T > (item);
q.Next
= p;
r.Next
= q;
}


}
// 在单链表的第i个结点的位置后插入一个值为item的元素
public void InsertPost(T item, int i)
{
if (IsEmpty() || i < 1 )
{
Console.WriteLine(
" List is empty or Position is error " );
return ;
}
if (i == 1 )
{
Node
< T > q = new Node < T > (item);
q.Next
= head.Next;
head.Next
= q;
return ;
}
Node
< T > p = head;
int j = 1 ;

while (p != null && j < i)
{
p
= p.Next;
++ j;
}
if (j == i)
{
Node
< T > q = new Node < T > (item);
q.Next
= p.Next;
p.Next
= q;

}
}
// 删除单链表的第i个结点
public T Delete( int i)
{
if (IsEmpty() || i < 0 )
{
Console.WriteLine(
" List is empty or Position is error " );
return default (T);
}
Node
< T > q = new Node < T > ();
if (i == 1 )
{
q
= head;
head
= head.Next;
return q.Data;
}
Node
< T > p = head;
int j = 1 ;
while (p.Next != null && j < i)
{
++ j;
q
= p;
p
= p.Next;
}
if (j == i)
{
q.Next
= p.Next;
return p.Data;
}
else
{
Console.WriteLine(
" The ith node is not exist " );
return default (T);
}



}

// 获得单链表的第i个数据元素
public T GetElem( int i)
{
if (IsEmpty())
{
Console.WriteLine(
" List is empty " );
return default (T);
}
Node
< T > p = new Node < T > ();
p
= head;
int j = 1 ;
while (p.Next != null && j < i)
{
++ j;
p
= p.Next;
}
if (j == i)
{
return p.Data;
}
else
{
Console.WriteLine(
" The ith node is not exist " );
return default (T);
}
}
// 在单链表中查找值为value的结点
public int Locate(T value)
{
if (IsEmpty())
{
Console.WriteLine(
" List is Empty " );
return - 1 ;
}
Node
< T > p = new Node < T > ();
p
= head;
int i = 1 ;
while ( ! p.Data.Equals(value) && p.Next != null )
{
p
= p.Next;
++ i;
}
return i;
}
// 在尾部插入结点建立单链表的算法
public LinkList < int > CreatLListHead()
{
int d;
LinkList
< int > L = new LinkList < int > ();

d
= Int32.Parse(Console.ReadLine());

while (d != - 1 )
{
Node
< int > p = new Node < int > ();
p.Next
= L.Head;
L.Head
= p;
d
= Int32.Parse(Console.ReadLine());
}
return L;
}
// 将两个表合成一表的算法
// public LinkList<int> Merge(LinkList<int> Ha, LinkList<int> Hb)
// {
// LinkList<int> Hc = new LinkList<int>();

// }
// 复制单链表的算法
public LinkList < int > LinkClone(LinkList < int > la)
{
LinkList
< int > lb = new LinkList < int > ();

Node
< T > p = new Node < T > ();
p
= head;
int j = 1 ;
while (p.Next != null && j < 100 )
{
lb.Append(la.GetElem(j));
j
++ ;
}


return lb;
}
// 输入全部的节点
public void Display()
{
Node
< T > p = new Node < T > ();
p
= head;
int j = 0 ;
while (p.Next != null && j < 100 )
{
Console.WriteLine(p.Data);
p
= p.Next;
j
++ ;
}


}

 

 

  

 

转载于:https://www.cnblogs.com/ScriptZhang/archive/2010/05/21/1740598.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值