C#数据结构与算法系列(六):链表——双链表(Double-LinkedList)
1.对比单向链表
单向链表查找的方向只能是一个方向,而双向链表可以向前或者向后查找
单向链表不能自我删除,需要靠辅助节点,而双向链表可以自我删除
对于单向链表的删除,我们首先要找到单向链表待删除节点的前一个节点,然后前一个节点的下一个节点指向删除节点的后一个节点。
2.双向链表的思路
3.代码实现
public class ListNode
{
public ListNode(int id, string name, string nickName)
{
this.Id = id;
this.Name = name;
this.NickName = nickName;
}
public int Id { get; set; } public string Name { get; set; } public string NickName { get; set; } public ListNode Next { get; set; } public ListNode Pre { get; set; }
}
public class DoubleLinkedList
{
public ListNode HeadNode; public DoubleLinkedList()
{
HeadNode = new ListNode(, "", "");
} public void GetList()
{
var temp = HeadNode.Next; while (temp != null)
{
Console.WriteLine($"id={temp.Id},name={temp.Name},nickName={temp.NickName}"); temp = temp.Next;
}
} public void Add(ListNode listNode)
{
var temp = HeadNode; //如果temp.Next为null就表示temp为最后一个节点;
while (temp.Next != null)
{
temp = temp.Next;
}
//把最后的节点指向待添加的节点
temp.Next = listNode; //将待添加的前一个节点指向temp
listNode.Pre = temp;
} public void Update(ListNode listNode)
{
var temp = HeadNode; //bool flag = false; while (temp.Next != null)
{
if (temp.Next.Id == listNode.Id)
{
//flag = true;
temp.Next.Name = listNode.Name; temp.Next.NickName = listNode.NickName; break;
} temp = temp.Next;
} //if (flag)
//{
// temp.Next.Name = listNode.Name;
// temp.Next.NickName = listNode.NickName;
//}
//else Console.WriteLine("未找到");
} public void Delete(int id)
{
/*{
var temp = HeadNode; while (temp.Next != null)
{
if (temp.Next.Id == id)
{
if (temp.Next.Next != null)
temp.Next.Next.Pre = temp;
temp.Next.Pre.Next = temp.Next.Next;
}
temp = temp.Next;
}
}*/ var temp = HeadNode.Next; while (temp != null)
{
if (temp.Id == id)
{
//如果是最后一个节点,那么就不需要执行下面的temp.Next.Pre = temp.Pre;
if (temp.Next != null) temp.Next.Pre = temp.Pre;//将temp的后一个节点的前一个指针指向temp的前一个节点 temp.Pre.Next = temp.Next;//将temp的前一个节点的后一个指针指向temp的后一个节点
} temp = temp.Next;
}
} public static void Test()
{
Console.WriteLine("双向链表的测试\n"); ListNode listNode1 = new ListNode(, "宋江", "及时雨");
ListNode listNode2 = new ListNode(, "卢俊义", "玉麒麟");
ListNode listNode3 = new ListNode(, "吴用", "智多星");
ListNode listNode4 = new ListNode(, "林冲", "豹子头"); DoubleLinkedList linkedList = new DoubleLinkedList(); //添加链表数据
linkedList.Add(listNode1);
linkedList.Add(listNode2);
linkedList.Add(listNode3);
linkedList.Add(listNode4); //获取链表所有数据
linkedList.GetList(); linkedList.Update(new ListNode(, "宋", "及时")); Console.WriteLine("\n获取链表修改后的所有数据\n");
linkedList.GetList(); linkedList.Delete(); Console.WriteLine("\n获取链表删除后的所有数据\n");
linkedList.GetList();
}
}
C#数据结构与算法系列(六):链表——双链表(Double-LinkedList)的更多相关文章
- 数据结构与算法系列2 线性表 链表的分类+使用java实现链表+链表源码详解
数据结构与算法系列2.2 线性表 什么是链表? 链表是一种物理存储单元上非连续,非顺序的存储结构,数据元素的逻辑顺序是通过链表的链接次序实现的一系列节点组成,节点可以在运行时动态生成,每个节点包括两个 ...
- javascript实现数据结构与算法系列:栈 -- 顺序存储表示和链式表示及示例
栈(Stack)是限定仅在表尾进行插入或删除操作的线性表.表尾为栈顶(top),表头为栈底(bottom),不含元素的空表为空栈. 栈又称为后进先出(last in first out)的线性表. 堆 ...
- C# 数据结构 - 单链表 双链表 环形链表
链表特点(单链表 双链表) 优点:插入和删除非常快.因为单链表只需要修改Next指向的节点,双链表只需要指向Next和Prev的节点就可以完成插入和删除操作. 缺点:当需要查找某一个节点的时候就需要一 ...
- 数据结构与算法系列2 线性表 使用java实现动态数组+ArrayList源码详解
数据结构与算法系列2 线性表 使用java实现动态数组+ArrayList源码详解 对数组有不了解的可以先看看我的另一篇文章,那篇文章对数组有很多详细的解析,而本篇文章则着重讲动态数组,另一篇文章链接 ...
- 数据结构与算法之PHP实现链表类(单链表/双链表/循环链表)
链表是由一组节点组成的集合.每个节点都使用一个对象的引用指向它的后继.指向另一个节点的引用叫做链表. 链表分为单链表.双链表.循环链表. 一.单链表 插入:链表中插入一个节点的效率很高.向链表中插 ...
- 数据结构与算法系列研究七——图、prim算法、dijkstra算法
图.prim算法.dijkstra算法 1. 图的定义 图(Graph)可以简单表示为G=<V, E>,其中V称为顶点(vertex)集合,E称为边(edge)集合.图论中的图(graph ...
- 《数据结构与算法之美》 <05>链表(下):如何轻松写出正确的链表代码?
想要写好链表代码并不是容易的事儿,尤其是那些复杂的链表操作,比如链表反转.有序链表合并等,写的时候非常容易出错.从我上百场面试的经验来看,能把“链表反转”这几行代码写对的人不足 10%. 为什么链表代 ...
- javascript实现数据结构与算法系列:循环链表与双向链表
循环链表(circular linked list) 是另一种形式的链式存储结构.它的特点是表中最后一个结点的指针域指向头结点,整个表形成一个环. 循环链表的操作和线性链表基本一致,仅有细微差别. w ...
- 数据结构与算法系列研究五——树、二叉树、三叉树、平衡排序二叉树AVL
树.二叉树.三叉树.平衡排序二叉树AVL 一.树的定义 树是计算机算法最重要的非线性结构.树中每个数据元素至多有一个直接前驱,但可以有多个直接后继.树是一种以分支关系定义的层次结构. a.树是n ...
随机推荐
- zwx_helper 只用小括号()和中括号[ ] 轻松开发wxWidgets
https://github.com/bbqz007/zhelper-wxWidgets https://github.com/bbqz007/zhelper-wxWidgets/tree/maste ...
- Kubernetes Ingress简单入门
作者:Nick Ramirez 原文链接:https://thenewstack.io/kubernetes-ingress-for-beginners/ 本文转载自Rancher Labs 不知道你 ...
- 【JUC】CyclicBarrier和Semaphore的使用
CyclicBarrier的使用 CyclicBarrier:可以让一组检测到一个屏障时被阻塞,直到最后一个线程到达屏障时,屏障才会开门,所有的屏障拦截的线程才会继续执行,线程进入屏障通过Cyclic ...
- Spring基础之IOC
一.ioc能解决什么问题 1.Spring是什么 spring是以ioc和aop为核心,能整合第三方框架和类库的企业级应用开源框架. 2.程序的耦合问题 例子:Driver类必须存在,编译才通过,Jd ...
- js中 addEventListener 和removeEventListener
js中添加事件监听本来是非常常见的事情,但是去除监听一般很少去干,最近项目中需要监听页面显示或者隐藏 代码如下 document.addEventListener(visibilitychange', ...
- Golang源码学习:调度逻辑(四)系统调用
Linux系统调用 概念:系统调用为用户态进程提供了硬件的抽象接口.并且是用户空间访问内核的唯一手段,除异常和陷入外,它们是内核唯一的合法入口.保证系统的安全和稳定. 调用号:在Linux中,每个系统 ...
- 【转】sql用逗号连接多张表对应哪个join?
逗号连接查询(用where连接条件): select order.id, order.orderdate,employee.id,employee.name from order,employee w ...
- 从 React 架构开始讲解 useState、useEffect 编程设计
随着前端开发复杂度增加,原生开发模式显得越来越笨重,前端框架也层出不穷. MVC 和 MVVM MVC MVC是模型(model)-视图(view)-控制器(controller)的缩写,一种软件设计 ...
- Java-接口(另类抽象)
1.1 特点 用interface定义 接口中所有成员变量都默认是由public static final修饰的 接口中所有方法都默认是由public abstract修饰的 接口没有构造器 接口采用 ...
- Rocket - debug - TLDebugModuleInner - ROM Generation
https://mp.weixin.qq.com/s/j_CgHU4PnY82NMwJzOqHYg 简单介绍Variable ROM Generation. 1. jalAbstract jalAbs ...