一、任务一:双向链表的创建,添加和删除
(1)提供数据的个数,头节点,尾节点
(2)增加数据到链表最后
(3)删除指定位置节点
二、数据结构定义
1、双向链表节点类
/// <summary>
/// 双向链表节点类
/// </summary>
/// <typeparam name="T">泛型类型参数</typeparam>
class DoubleLinkNode<T>
{
public T data; // 节点存储的数据
public DoubleLinkNode<T> nextNode; // 指向下一个节点的指针
public DoubleLinkNode<T> LastNode; // 指向上一个节点的指针
/// <summary>
/// 节点构造函数
/// </summary>
/// <param name="data">节点数据</param>
public DoubleLinkNode(T data)
{
this.data = data;
}
}
节点特性:
-
包含数据域
data -
前驱指针
LastNode指向前一个节点 -
后继指针
nextNode指向后一个节点
三、核心功能实现
双向链表类框架
/// <summary>
/// 双向链表类
/// </summary>
/// <typeparam name="T">泛型类型参数</typeparam>
class DoubleLinkList<T>
{
public DoubleLinkNode<T> head; // 链表头节点
public DoubleLinkNode<T> last; // 链表尾节点
// 添加、删除、显示等方法...
}
1. 添加操作 (Add)
/// <summary>
/// 向链表尾部添加新元素
/// </summary>
/// <param name="value">要添加的值</param>
public void Add(T value)
{
DoubleLinkNode<T> node = new DoubleLinkNode<T>(value);
if (head == null) // 链表为空的情况
{
head = node;
last = node;
}
else // 链表非空的情况
{
node.LastNode = last; // 新节点的前驱指向原尾节点
last.nextNode = node; // 原尾节点的后继指向新节点
last = node; // 更新尾节点为新节点
}
}
添加操作流程:
-
创建新节点
-
如果链表为空,设置头和尾都指向新节点
-
如果链表非空,将新节点连接到链表尾部
-
更新尾指针
2. 删除操作 (Remove)
/// <summary>
/// 删除指定索引位置的节点
/// </summary>
/// <param name="index">要删除的节点索引</param>
public void Remove(int index)
{
// 计算链表长度
int count = 0;
DoubleLinkNode<T> current = head;
while (current != null)
{
count++;
current = current.nextNode;
}
// 检查索引有效性
if (index < 0 || index >= count)
{
Console.WriteLine("索引超出范围");
return;
}
// 删除头节点
if (index == 0)
{
head = head.nextNode;
if (head == null) // 如果链表只有一个节点
{
last = null;
}
else
{
head.LastNode = null; // 新头节点的前驱设为null
}
return;
}
// 删除尾节点
if (index == count - 1)
{
last = last.LastNode; // 尾指针指向前一个节点
last.nextNode = null; // 新的尾节点后继设为null
return;
}
// 删除中间节点
current = head;
for (int i = 0; i < index; i++)
{
current = current.nextNode; // 移动到要删除的节点
}
// 跳过要删除的节点,重新连接前后节点
current.LastNode.nextNode = current.nextNode;
current.nextNode.LastNode = current.LastNode;
}
删除操作的三种情况:
-
删除头节点:更新head指针,处理前驱关系
-
删除尾节点:更新last指针,处理后继关系
-
删除中间节点:重新连接前后节点
3. 显示操作 (Show)
/// <summary>
/// 显示链表中所有元素
/// </summary>
public void Show()
{
DoubleLinkNode<T> node = head;
while (node != null)
{
Console.WriteLine(node.data); // 输出当前节点数据
node = node.nextNode; // 移动到下一个节点
}
}
四、完整代码
using System;
using System.Collections.Generic;
namespace DoubleLinkedListExample
{
// 双向链表节点类
class DoubleLinkNode<T>
{
public T data;
public DoubleLinkNode<T> nextNode;
public DoubleLinkNode<T> LastNode;
public DoubleLinkNode(T data)
{
this.data = data;
}
}
// 双向链表类
class DoubleLinkList<T>
{
public DoubleLinkNode<T> head;
public DoubleLinkNode<T> last;
// 添加方法
public void Add(T value)
{
DoubleLinkNode<T> node = new DoubleLinkNode<T>(value);
if (head == null)
{
head = node;
last = node;
}
else
{
node.LastNode = last;
last.nextNode = node;
last = node;
}
}
// 删除方法
public void Remove(int index)
{
int count = 0;
DoubleLinkNode<T> current = head;
while (current != null)
{
count++;
current = current.nextNode;
}
if (index < 0 || index >= count)
{
Console.WriteLine("索引超出范围");
return;
}
if (index == 0)
{
head = head.nextNode;
if (head == null)
{
last = null;
}
else
{
head.LastNode = null;
}
return;
}
if (index == count - 1)
{
last = last.LastNode;
last.nextNode = null;
return;
}
current = head;
for (int i = 0; i < index; i++)
{
current = current.nextNode;
}
current.LastNode.nextNode = current.nextNode;
current.nextNode.LastNode = current.LastNode;
}
// 显示方法
public void Show()
{
DoubleLinkNode<T> node = head;
while (node != null)
{
Console.WriteLine(node.data);
node = node.nextNode;
}
}
}
class Program
{
static void Main(string[] args)
{
TestDoubleLinkedList();
}
static void TestDoubleLinkedList()
{
DoubleLinkList<int> list = new DoubleLinkList<int>();
// 测试添加操作
Console.WriteLine("=== 添加元素测试 ===");
list.Add(1);
list.Add(2);
list.Add(3);
list.Show();
Console.WriteLine("\n=== 继续添加并删除测试 ===");
list.Add(4);
list.Add(5);
list.Remove(2); // 删除索引为2的元素(值为3)
list.Add(6); // 添加新元素
list.Show();
}
}
}
347

被折叠的 条评论
为什么被折叠?



