第3章 线性表的单链表c#实现---《大话数据结构》读书笔记
2012-01-11 17:02 海不是蓝 阅读(1448) 评论(1) 编辑 收藏 举报线性表的链式存储结构(单链表)
定义
为了表示每个数据元素ai与其直接后继数据元素ai+1之间的逻辑关系,对数据元素ai来说,除了存储其本身的信息之外,还需要存储一个指示其直接后继的信息(即直接后继的存储位置)。把存储数据元素信息的域称为数据域,把存储直接后继位置的域称为指针域。指针域中存储的信息称作指针链,这两部分信息组成数据元素ai的存储映象,称为结点(Node)。
n个结点(ai的存储映像)链结成为一个链表,即为线性表(ai,a2,…,an)的链式存储结构,因为此链表的每一个结点中只包含一个指针域,所以叫做单链表。
链表中第一个结点的存储位置叫做头指针。
单链表的读取
从头开始找,当i=1的时候,就直接取出数据了。当i=n的时候,需要遍历n-1次,如果位置n-1的结点的next指针不是null,那么就找到了。最坏的时间复杂度为O(n)。
单链表的优势在于插入和删除。但是查找就是鸡肋了。
单链表的插入
假设存储元素e的结点为s,要实现结点p,p->next和s之间的逻辑关系的变化,只需要将结点s插入到结点p和p->next之间即可。让p的后继结点改成s的后继结点,然后把结点s变成p的后继结点。
单链表的删除
设存储元素ai的结点为q,要实现讲结点q删除单链表的操作,其实就是将它的前继结点的指针绕过,指向它的后继结点即可。
单链表的删除和插入的时间复杂度都是O(n),
清空操作
清空操作是指清除单链表中的所有结点,使单链表为空。这里设置head=null。然后等待垃圾回收器进行回收。这里不需要我们自己去处理。而顺序表的清空只是设置一个索引=-1,但是数组的空间还是在,只是外部无法访问元素。
单链表结构与顺序存储结构的优缺点
存储分配方式 |
时间性能 |
空间性能 |
*顺序表的存储结构用一段连续的存储单元依次存储线性表的数据元素。 *单链表采用链式存储结构,用一组任意的存储单元存放线性表的元素 |
*查找 顺序存储结构O(1) 单链表O(n) *插入和删除 顺序存储结构O(n) 单链表O(1) |
*顺序表需要预分配存储空间 *单链表不需要预分配存储空间 |
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
{
static void Main(string[] args)
{
Console.WriteLine("------添加3个节点------");
LinkList<Test> list = new LinkList<Test>();
list.Append(new Test("aaa", 1));
list.Append(new Test("bbb", 2));
list.Append(new Test("ccc", 3));
Show(list.Head);
Console.WriteLine("长度:{0}", list.GetLength());
Console.WriteLine("判断单链表是否为空:{0}", list.IsEmpty());
Console.WriteLine("------在第2个节点前插入1个节点------");
list.Insert(new Test("aaa1", 11), 2);
Show(list.Head);
Console.WriteLine("长度:{0}", list.GetLength());
Console.WriteLine("判断单链表是否为空:{0}", list.IsEmpty());
Console.WriteLine("------在第3个节点后插入1个节点------");
list.InsertPost(new Test("bbb1", 222), 3);
Show(list.Head);
Console.WriteLine("长度:{0}", list.GetLength());
Console.WriteLine("判断单链表是否为空:{0}", list.IsEmpty());
Console.WriteLine("------删除第4个节点------");
list.Delete(4);
Show(list.Head);
Console.WriteLine("长度:{0}", list.GetLength());
Console.WriteLine("判断单链表是否为空:{0}", list.IsEmpty());
Console.WriteLine("------获取第3个节点------");
Test t = list.GetElem(3);
Console.WriteLine("name={0} age={1}", t.Name, t.Age);
Console.WriteLine("长度:{0}", list.GetLength());
Console.WriteLine("判断单链表是否为空:{0}", list.IsEmpty());
Console.WriteLine("------查找------");
Console.WriteLine("位置:{0}", list.Locate(new Test("bbb", 2)));
Console.WriteLine("name={0} age={1}", t.Name, t.Age);
Console.WriteLine("长度:{0}", list.GetLength());
Console.WriteLine("判断单链表是否为空:{0}", list.IsEmpty());
Console.WriteLine("------清空单链表------");
list.Clear();
Console.WriteLine("长度:{0}", list.GetLength());
Console.WriteLine("判断单链表是否为空:{0}", list.IsEmpty());
Console.Read();
}
static void Show(Node<Test> node)
{
Node<Test> p = node;
while (p.Data != null)
{
Console.WriteLine("name:{0} age:{1}", p.Data.Name, p.Data.Age);
if (p.Next == null)
break;
else
p = p.Next;
}
}
}
public class Test
{
public Test(string name, UInt16 age)
{
this.name = name;
this.age = age;
}
private string name;
public string Name
{
get { return name; }
set { name = value; }
}
private UInt16 age;
public UInt16 Age
{
get { return age; }
set { age = value; }
}
//重写Equals,判断对象的相等性而不是同一性
public override bool Equals(object obj)
{
if (obj == null)
return false;
if (this.GetType() != obj.GetType())
return false;
Test obj1 = (Test)obj;
if (obj1.Age != this.Age || obj1.Name != this.Name)
return false;
return true;
}
}
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; }
}
}
public interface IListDS<T>
{
Int32 GetLength();//求长度
void Clear();//清空操作
bool IsEmpty();//判断线性表是否为空
void Append(T item);//附加操作
void Insert(T item, Int32 i);//插入操作
T Delete(Int32 i);//删除操作
T GetElem(Int32 i);///获取表元
Int32 Locate(T value);//按值查找
}
public class LinkList<T> : IListDS<T>
{
private Node<T> head;
//头引用属性
public Node<T> Head
{
get { return head; }
set { head = value; }
}
//构造器
public LinkList()
{
head = null;
}
//求单链表的长度
public Int32 GetLength()
{
Node<T> p = head;
Int32 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个节点的位置前插入一个节点
public void Insert(T item, Int32 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>();
Int32 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, Int32 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;
Int32 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(Int32 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;
Int32 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 node is not exist");
return default(T);
}
}
//获取单链表的第i个数据元素
public T GetElem(Int32 i)
{
if (IsEmpty())
{
Console.WriteLine("List is empty");
return default(T);
}
Node<T> p = new Node<T>();
p = head;
Int32 j = 1;
while (p.Next != null && j < i)
{
++j;
p = p.Next;
}
if (j == i)
{
return p.Data;
}
else
{
Console.WriteLine("The node is not exist");
return default(T);
}
}
//在单链表中查找值为value的节点
public Int32 Locate(T value)
{
if (IsEmpty())
{
Console.WriteLine("List is Empty");
return -1;
}
Node<T> p = new Node<T>();
p = head;
Int32 i = 1;
while (!p.Data.Equals(value) && p.Next != null)
{
p = p.Next;
++i;
}
return i;
}
}