双向链表图解
程序实现
下面的实现中没有使用头节点(即头节点就是首节点)
Node类
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace test
{
class Node
{
T data; //数据域
Node next; //后继节点
Node pre; //前驱节点
internal Node Next { get => next; set => next = value; }
internal Node Pre { get => pre; set => pre = value; }
public T Data { get => data; set => data = value; }
//构造器
public Node(T value, Node next, Node pre)
{
Data = value;
Next = next;
Pre = pre;
}
//构造器
public Node(T value)
{
Data = value;
}
//构造器
public Node(Node next,Node pre)
{
Next = next;
Pre = pre;
}
//构造器
public Node(Node next)
{
Next = next;
}
//构造器
public Node()
{
Data = default(T);
Next = null;
Pre = null;
}
}
}
DoubleList类
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace test
{
class DoubleList
{
Node head; //头节点
internal Node Head { get => head; set => head = value; }
//构造器
public DoubleList() { Head = null; }
///
/// 链表判空
///
/// 为空返回true
public bool IsEmpty() { return Head == null; }
///
/// 取链表长度
///
/// 链表长度
public int GetLenth()
{
//链表为空
if (IsEmpty()) { return 0; }
//只有一个元素
if (Head.Next == null) { return 1; }
//遍历链表
Node c = Head;
int i = 1;
while (c.Next != null)
{
c = c.Next;
++i;
}
return i;
}
///
/// 在末尾添加新元素
///
public void Append(T value)
{
Node item = new Node(value);
//链表为空时,直接覆盖首节点
if (IsEmpty()) { Head = item; return; }
//只有一个元素时,直接挂载
if (Head.Next == null)
{
Head.Next = item;
item.Pre = Head;
return;
}
//遍历至末尾添加
Node c = Head;
while (c.Next != null) { c = c.Next; }
c.Next = item;
item.Pre = c;
}
///
/// 在指定位置后插入元素
///
/// 元素值
/// 元素位置
public void Insert(T value, int i)
{
//插入位置大于链表总长度
if (GetLenth() < i)
{
Console.WriteLine("插入位置不正确");
return;
}
Node c = new Node(value);//新节点
//插入到头节点位置
if (i == 1)
{
Head.Next.Pre = c; //头节点的后继节点的前驱指向新节点
c.Next = Head.Next; //新节点的后继指向头节点的后继节点
c.Pre = Head; //新节点的前驱指向头节点
Head.Next = c; //头节点的后继指向新节点
return;
}
//遍历插入
int j = 1;
Node cur = Head;
while (cur.Next != null && i > j)
{
cur = cur.Next;
++j;
}
if (j == i)
{
cur.Next.Pre = c; //当前节点的后继节点的前驱指向新节点
c.Next = cur.Next; //新节点的后继指向当前节点
c.Pre = cur; //新节点的前驱指向当前节点
cur.Next = c; //当前节点的后继指向新节点
}
else
{
Console.WriteLine("位置错误");
}
}
///
/// 删除指定位置的元素
///
///
public void Delete(int i)
{
if (GetLenth() < i)
{
Console.WriteLine("位置不正确");
return;
}
//删除首节点
if (i == 1)
{
Head = Head.Next;
Head.Pre = null;
return;
}
//遍历删除
Node c = Head;
int j = 1;
while (c.Next != null && j < i)
{
c = c.Next;
++j;
}
if (j == i)
{
//如果是最后一个节点,直接将其前驱节点的后继节点置为空,将其前驱节点置为空
if (c.Next == null)
{
c.Pre.Next = null;
c.Pre = null;
}
else
{
c.Next.Pre = c.Pre;
c.Pre.Next = c.Next;
}
}
else {
Console.WriteLine("位置错误");
}
}
///
/// 根据位置获取元素值
///
/// 元素位置
/// 元素值
public T GetElem(int i)
{
if (GetLenth() < i)
{
Console.WriteLine("位置不正确");
return default(T);
}
if (i == 1)
{
return Head.Data;
}
Node c = Head;
int j = 1;
while (c.Next != null && j < i)
{
c = c.Next;
++j;
}
if (i == j)
{
return c.Data;
}
else
{
Console.WriteLine("位置错误");
return default(T);
}
}
///
/// 根据元素值,获取元素位置
///
///
///
public int GetPos(T data)
{
if (IsEmpty())
{
Console.WriteLine("链表为空");
return -1;
}
if (Head.Data.Equals(data))
{
return 1;
}
Node c = Head;
int i = 1;
int length = GetLenth();
while (c != null && !c.Data.Equals(data) && i <= length)
{
c = c.Next;
++i;
}
if (i <= length)
return i;
else
return -1;
}
}
}
Program类
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace test
{
class Program
{
static void Main(string[] args)
{
DoubleList link = new DoubleList();
link.Append("123");
link.Append("456");
link.Append("789");
//link.Insert("qwe", 1);
//link.Insert("asd", 2);
//link.Delete(2);
//Console.WriteLine(link.GetElem(1));
Console.WriteLine(link.GetPos("789"));
Node c = link.Head;
Console.WriteLine("---正序输出");
while (c.Next!=null) {
Console.WriteLine(c.Data);
c = c.Next;
}
Console.WriteLine(c.Data);
Console.WriteLine("---逆序输出");
while (c != null)
{
Console.WriteLine(c.Data);
c = c.Pre;
}
Console.WriteLine("---长度");
Console.WriteLine(link.GetLenth());
}
}
}