线性表之链表
来源:互联网 发布:手机网络慢怎么解决 编辑:程序博客网 时间:2024/06/05 04:57
1,为什么要使用链表
通过上一篇的学习,我们知道顺序表存在一些问题,主要有以下两个方面。
1,顺序表的长度是固定的,如果超出分配的长度就会造成溢出,如果存放的数据太少则会造成空间浪费。
2,在插入元素和删除元素时(尤其不在尾部时),会移动大量的元素,造成性能和效率低下。
基于以上问题,使用链表可以很好地避免顺序表中出现的问题。这也是我们要使用链表的原因。
通过上一篇的学习,我们知道顺序表存在一些问题,主要有以下两个方面。
1,顺序表的长度是固定的,如果超出分配的长度就会造成溢出,如果存放的数据太少则会造成空间浪费。
2,在插入元素和删除元素时(尤其不在尾部时),会移动大量的元素,造成性能和效率低下。
基于以上问题,使用链表可以很好地避免顺序表中出现的问题。这也是我们要使用链表的原因。
2,链表的存储结构:
从上图可以看出,单链表中的每个结点都包含一个“数据域”和一个“指针域”。“数据域”中包含当前结点的数据,“指针域”包含下一节点的存储地址,头指针head是指向开始结点的,结束结点没有后继结点,所以结束结点的指针域为空,即null。
3,链表的常用操作及实现代码
链表常用的操作有:
1,插入结点到表头
思路:将head头指针的next指针给新增结点的next,然后将整个新增结点给head头指针的next。因此时间复杂度为O(1)。
示意图:
2,插入结点到表尾
思路:插入方法与插入到表头一样,只不过多一个步骤就是通过head头指针循环找到终端结点。因此时间复杂度为O(n)。
示意图:
3,插入结点(1≤i≤ListLength(L))
思路:插入方法与插入到表头一样,多循环查找当前结点的动作。因此时间复杂度为O(n)。
示意图:
4,删除结点
思路:同插入结点一样,时间复杂度为O(n)。
示意图:
5,查找结点
思路:与插入结点和删除结点方法类似,时间复杂度为O(n)。
6,获取链表长度
思路:不像顺序表是连续存储的,获取表的长度非常容易。在链表中,数据不是连续存储的,因此需要循环遍历才能求得链表的长度,所以时间复杂度为O(n)。
namespace DS.BLL{ /// <summary> /// 封装链表的常用操作 /// </summary> public class ChainListBLL { /// <summary> /// 插入结点在表头 /// </summary> /// <typeparam name="T"></typeparam> /// <param name="head"></param> /// <param name="data"></param> /// <returns></returns> public static Node<T> InsertFirst<T>(Node<T> head, T data) { //创建一个新结点 Node<T> node = new Node<T>(); node.data = data; node.next = head; head = node; return head; } /// <summary> /// 插入结点在表尾 /// </summary> /// <typeparam name="T"></typeparam> /// <param name="head"></param> /// <param name="data"></param> /// <returns></returns> public static Node<T> InsertEnd<T>(Node<T> head, T data) { //创建一个新结点 Node<T> node = new Node<T>(); node.data = data; node.next = null; //空链表直接返回新增的结点 if (head == null) { head = node; return head; } GetLastNode(head).next = node; return head; } /// <summary> /// 插入结点(在包含关键字key的结点之后插入新的结点) /// </summary> /// <typeparam name="T"></typeparam> /// <param name="head"></param> /// <param name="data"></param> /// <returns></returns> public static Node<T> Insert<T,W>(Node<T> head,string key,Func<T,W> where, T data) where W:IComparable { //检查链表是否为空 if (head == null) return null; //查找包含关键字key的结点 if (where(head.data).CompareTo(key) == 0) { Node<T> node = new Node<T>(); node.data = data; node.next = head.next; //注意这里顺序不要弄反了 head.next = node; } Insert(head.next,key,where,data); //用递归继续查找下一个结点 return head; } /// <summary> /// 删除结点(删除包含关键字key的结点) /// </summary> /// <typeparam name="T"></typeparam> /// <typeparam name="W"></typeparam> /// <param name="head"></param> /// <param name="key"></param> /// <param name="where"></param> /// <returns></returns> public static Node<T> Delete<T, W>(Node<T> head, string key, Func<T, W> where) where W : IComparable { if (head == null) return null; //如果只有一个结点 if (where(head.data).CompareTo(key) == 0) { if (head.next != null) head = head.next; //向后移动指针 else return head = null; } else { //判断此结点是否是要删除结点的前一结点 while (head.next != null && where(head.next.data).CompareTo(key) == 0) { head.next = head.next.next; } } Delete(head.next,key,where); //使用递归继续查找 return head; } /// <summary> /// 查找结点(查找包含关键字key的结点) /// </summary> /// <typeparam name="T"></typeparam> /// <typeparam name="W"></typeparam> /// <param name="head"></param> /// <param name="key"></param> /// <param name="where"></param> /// <returns></returns> public static Node<T> GetNodeByKey<T, W>(Node<T> head, string key, Func<T, W> where) where W : IComparable { if (head == null) return null; if (where(head.data).CompareTo(key) == 0) return head; return GetNodeByKey(head.next,key,where); } /// <summary> /// 获取链表长度 /// </summary> /// <typeparam name="T"></typeparam> /// <param name="head"></param> /// <returns></returns> public static int GetLength<T>(Node<T> head) { int count = 0; while (head != null) { head = head.next; //移动指针 count++; } return count; } private static Node<T> GetLastNode<T>(Node<T> head) { if (head.next == null) return head; //最后结点 return GetLastNode(head.next); //使用递归继续查找 } } /// <summary> /// 封装链表 /// </summary> /// <typeparam name="T"></typeparam> public class Node<T> { public T data; //数据 public Node<T> next; //指针 }}
0 0
- 线性表之链表
- 线性表之链表
- 线性表之链表
- 线性表之链表
- 线性表之链表
- 线性表之链表
- 线性表之链表
- 线性表之链表
- 线性表之链表
- 线性表之链表
- 之线性链表小结
- 线性链表之123
- 数据结构之线性链表
- 数据结构之: 线性链表
- 数据结构之线性链表
- 数据结构之线性链表
- 数据结构之线性链表
- 数据结构之线性链表
- 读写磁盘
- 关于数据库范式
- git 撤销commit
- eclipse中Refresh Gradle Project时遇到Supplied javaHome is not a valid folder错误
- Spring/Tomcat Rest开发 配置UTF-8编码
- 线性表之链表
- 关于递推
- C# 反射获取 Metadata类,获取类的Attribute 属性
- Java面试(五)
- Session和cookie详解
- 今天在老项目上新建,发现老项目svn控制,需要去掉,记录下
- 项目开发计划模板
- 查看linux中某个端口(port)是否被占用
- Oracle之查询索引、索引列等信息