双向链表也叫双链表

embedded/2024/10/18 19:27:04/

双向链表也叫双链表

双向链表也叫双链表
每个节点都有两个指针,分别指向 直接前驱节点、直接后继节点

双向链表中任意一个节点,都可以通过通过它的前驱节点和后继节点,访问其他节点

节点如下
在这里插入图片描述
节点定义
ListNode
// 节点的值
T element;
// 前置节点
ListNode preNode;
// 后置节点
ListNode nextNode;

链表提供以下方法

项目Value
PushFront(T t)将元素插入到链表第一个位置
PushBack(T t)将元素插入到链表最后一个位置
Front()第一个节点
Back()最后一个节点
MakeEmpty()清空链表
IsEmpty()判断链表是否为空
Size()获取链表中数据个数
Find(T t)查找节点
Delete(T t)删除节点
Delete(ListNode node)删除节点
InsertAsNext(ListNode node, ListNode next)将 next 插入到 node 后
Begin()迭代器开始
End()迭代器结束
Deduplicate()无序链表删除重复元素
Uniquify()有序链表删除重复元素
List Traverse()迭代遍历获取所有元素
Swap(ListNode node1, ListNode node2)交换两个节点的值
Sort(Comparison comparison)排序,comparison 是比较函数

C# 代码实现如下

    /// <summary>/// 链表节点/// </summary>/// <typeparam name="T"></typeparam>public class ListNode<T> where T : IComparable<T>{// 节点的值private T element;// 前置节点private ListNode<T> preNode;// 后置节点private ListNode<T> nextNode;public ListNode(){}public ListNode(T v){element = v;}public ListNode(T v, ListNode<T> pre, ListNode<T> next){element = v;preNode = pre;nextNode = next;}public T Element{get { return element; }set { element = value; }}public ListNode<T> PreNode{get { return preNode; }set { preNode = value; }}public ListNode<T> NextNode{get { return nextNode; }set { nextNode = value; }}}/// <summary>/// 链表迭代器/// </summary>/// <typeparam name="T"></typeparam>public class LinkListIterator<T> where T : IComparable<T>{private ListNode<T> node;public LinkListIterator(ListNode<T> node){this.node = node;}public ListNode<T> Node{get { return node; }}public T Element{get{return node.Element;}}/// <summary>/// 重写 == 方法/// </summary>/// <param name="iteratorL"></param>/// <param name="iteratorR"></param>/// <returns></returns>public static bool operator ==(LinkListIterator<T> iteratorL, LinkListIterator<T> iteratorR){return null != iteratorL.node && null != iteratorR.node && iteratorL.node == iteratorR.node;}/// <summary>/// 重写 != 方法/// </summary>/// <param name="iteratorL"></param>/// <param name="iteratorR"></param>/// <returns></returns>public static bool operator !=(LinkListIterator<T> iteratorL, LinkListIterator<T> iteratorR){return null == iteratorL.node || null == iteratorR.node || iteratorL.node != iteratorR.node;}/// <summary>/// 重写 ++ 方法/// </summary>/// <param name="iterator"></param>/// <returns></returns>public static LinkListIterator<T> operator ++(LinkListIterator<T> iterator){iterator.node = iterator.node.NextNode;return iterator;}/// <summary>/// 重写 -- 方法/// </summary>/// <param name="iterator"></param>/// <returns></returns>public static LinkListIterator<T> operator --(LinkListIterator<T> iterator){iterator.node = iterator.node.PreNode;return iterator;}public override bool Equals(object obj){return base.Equals(obj);}public override int GetHashCode(){return base.GetHashCode();}}/// <summary>/// 链表/// </summary>/// <typeparam name="T"></typeparam>public class LinkList<T> where T : IComparable<T>{/// <summary>/// 头节点/// </summary>private ListNode<T> _header;/// <summary>/// 尾节点/// </summary>private ListNode<T> _trailer;  // 除去 头、尾,节点的个数private int _size;public LinkList(){// 为了减少操作上的复杂度// 头节点和尾节点一直存在,添加、删除都是在 头节点、尾节点 中间操作_header = new ListNode<T>();_trailer = new ListNode<T>();_header.PreNode = null;_header.NextNode = _trailer;_trailer.PreNode = _header;_trailer.NextNode = null;}/// <summary>/// 迭代器开始/// </summary>/// <returns></returns>public LinkListIterator<T> Begin(){return new LinkListIterator<T>(_header.NextNode);}/// <summary>/// 迭代器结束/// </summary>/// <returns></returns>public LinkListIterator<T> End(){return new LinkListIterator<T>(_trailer);}/// <summary>/// 第一个元素/// </summary>public ListNode<T> Front(){return Size() > 0 ? _header.NextNode : null;}/// <summary>/// 最后一个元素/// </summary>public ListNode<T> Back(){return Size() > 0 ? _trailer.PreNode : null;}/// <summary>/// 清空链表/// </summary>public void MakeEmpty(){_header.NextNode = _trailer;_trailer.PreNode = _header;_size = 0;}/// <summary>/// 链表为空/// </summary>public bool IsEmpty(){return _header.NextNode == _trailer;}/// <summary>/// 链表元素个数/// </summary>public int Size(){return _size;}/// <summary>/// 查找元素指针位置/// </summary>public ListNode<T> Find(T t){ListNode<T> temp = _header.NextNode;while (temp != _trailer){if (temp.Element.CompareTo(t) == 0){return temp;}temp = temp.NextNode;}return null;}/// <summary>/// 删除元素/// </summary>public void Delete(T t){ListNode<T> node = Find(t);Delete(node);}public void Delete(ListNode<T> node){if (null != node){node.PreNode.NextNode = node.NextNode;node.NextNode.PreNode = node.PreNode;--_size;}}/// <summary>/// 将元素插入到链表第一个位置/// </summary>/// <param name="t"></param>public void PushFront(T t){ListNode<T> newNode = new ListNode<T>(t);InsertAsPre(_header.NextNode, newNode);}/// <summary>/// 将元素插入到链表最后一个位置/// </summary>/// <param name="t"></param>public void PushBack(T t){ListNode<T> newNode = new ListNode<T>(t);InsertAsPre(_trailer, newNode);}private void InsertAsPre(ListNode<T> node, ListNode<T> next){InsertAsNext(node.PreNode, next);}/// <summary>/// 将 next 插入到 node 后/// </summary>/// <param name="node"></param>/// <param name="next"></param>public void InsertAsNext(ListNode<T> node, ListNode<T> next){if (node == _trailer){return;}next.PreNode = node;next.NextNode = node.NextNode;node.NextNode.PreNode = next;node.NextNode = next;++_size;}/// <summary>/// 无序链表删除重复元素/// </summary>public void Deduplicate(){for (ListNode<T> node = _header.NextNode; node != _trailer; node = node.NextNode){for (ListNode<T> temp = node.NextNode; temp != _trailer; temp = temp.NextNode){if (node.Element.CompareTo(temp.Element) == 0){Delete(temp);}}}}/// <summary>/// 有序链表删除重复元素/// </summary>public void Uniquify(){ListNode<T> node = _header.NextNode;while ( node != _trailer){ListNode<T> next = node.NextNode;if (next != _trailer && next.Element.CompareTo(node.Element) == 0){Delete(next);continue;}node = node.NextNode;}}/// <summary>/// 遍历/// </summary>public List<T> Traverse(){List<T> list = new List<T>();for (LinkListIterator<T> iterator = Begin(); iterator != End(); ++iterator){list.Add(iterator.Element);}return list;}/// <summary>/// 交换两个节点位置/// </summary>public void Swap(ListNode<T> node1, ListNode<T> node2){if (node1.NextNode == node2){Swap(node1.PreNode, node2.NextNode, node1, node2);}else if (node2.NextNode == node1){Swap(node2.PreNode, node1.NextNode, node2, node1);}else{Swap(node1.PreNode, node2.NextNode, node1, node2);}}/// <summary>/// 交换两个节点位置/// </summary>/// <param name="pre"></param>/// <param name="next"></param>/// <param name="node1"></param>/// <param name="node2"></param>private void Swap(ListNode<T> pre, ListNode<T> next, ListNode<T> node1, ListNode<T> node2){Delete(node1);Delete(node2);InsertAsNext(pre, node2);InsertAsPre(next, node1);}/// <summary>/// 排序/// </summary>public void Sort(Comparison<T> comparison){ListNode<T> begin = _header.NextNode;if (null == begin || begin.NextNode == _trailer){return;}for (ListNode<T> temp = begin.NextNode; temp != _trailer; temp = temp.NextNode){T element = temp.Element;ListNode<T> preNode = temp.PreNode;while (preNode != _header.NextNode.PreNode && comparison(preNode.Element, element) > 0){preNode.NextNode.Element = preNode.Element;preNode = preNode.PreNode;}preNode.NextNode.Element = element;}}}

http://www.ppmy.cn/embedded/6150.html

相关文章

IDM的实用功能!

IDM&#xff0c;全称Internet Download Manager&#xff0c;是一款功能强大的下载管理器&#xff0c;以其出色的下载速度、丰富的实用功能及高度的用户友好性赢得了广大用户的青睐。下面&#xff0c;我们将详细介绍IDM的实用功能。 首先&#xff0c;IDM支持多线程下载和多文件…

react中关于类式组件和函数组件对props、state、ref的使用

文章中有很多蓝色字体为扩展链接&#xff0c;可以补充查看。 常用命令使用规则 组件编写方式: 1.函数式 function MyButton() { //直接return 标签体return (<>……</>); }2.类 class MyButton extends React.Component { //在render方法中&#xff0c;return…

Hadoop1X,Hadoop2X和hadoop3X有很大的区别么?

Hadoop的演进从Hadoop 1到Hadoop 3主要是为了提供更高的效率、更好的资源管理、更高的可靠性以及对更多数据处理方式的支持。下面是Hadoop 1, Hadoop 2, 和 Hadoop 3之间的主要区别和演进的原因&#xff1a; Hadoop 1 特点&#xff1a; 主要包括两大核心组件&#xff1a;HDFS&a…

windows安装多版本node.js

首先&#xff0c;你需要安装 nvm。如果你还没有安装 nvm&#xff0c;你可以在 bash 或者其他类似的 shell 中运行以下命令进行安装&#xff1a; curl -o- https://raw.githubusercontent.com/nvm-sh/nvm/v0.38.0/install.sh | bash这将下载并运行 nvm 的安装脚本。注意&#xf…

天梯赛2024

2024年的天梯赛&#xff0c;即中国高校计算机大赛-团体程序设计天梯赛&#xff0c;是一项旨在推进大学生程序设计能力培养、增强团队合作精神、提高综合素质的重要赛事。以下是一些关于2024年天梯赛的信息&#xff1a; 1. **比赛组织**&#xff1a;该赛事由教育部高等学校计算…

怎么用3ds MAX制作蜂窝状模型?

1、新建多边形&#xff1a;打开3ds MAX软件&#xff0c;在样条线中新建一个多边形。 2、设置参数&#xff1a;切换到顶视图&#xff0c;设置多边形的参数&#xff0c;例如半径为10&#xff0c;变数为6&#xff0c;以形成一个六边形的基础。 3、复制并形成圆柱状&#xff1a;打开…

pycharm 更换Eclipse 的按键模式 keymap

流程 整体来说比较简单&#xff0c;其实只要下载一个eclipse keymap插件就可以完成 首先 ctrl alt s 打开设置页面&#xff0c;找到 plugin 安装完成后还是在 settings 下切换到 keymap即可以看到eclipse 的按键设置出现了&#xff0c;应用后ok 即可完成 再去试试&#x…

数据仓库作业五:第8章 关联规则挖掘

目录 第8章 关联规则挖掘作业题 第8章 关联规则挖掘 作业题 1、设4-项集 X { a , b , c , d } X\{a,b,c,d\} X{a,b,c,d}&#xff0c;试求出由 X X X 导出的所有关联规则。 解&#xff1a; 首先生成项集的所有非空真子集。这包括&#xff1a; { a } , { b } , { c } , {…