【数据结构】单链表,双端链表,有序链表
来源:互联网 发布:sql sum group by 编辑:程序博客网 时间:2024/05/29 19:46
- 单向链表
- 双端链表
- 有序链表
在刷LeetCode的时候遇到一道链表的题目 Merge Two Sorted Lists ,发现自己看不懂答案(毕竟没系统学习数据结构,T T) 。
于是乎痛下决心认真实践数据结构的学习。
链表和数组相比,插入和删除数据效率高。随机访问某个节点的数据不如数组来得快。
下面是Java实现的各种链表
单向链表
把链表的操作比作针线活,线是每一个节点之间的next
针是复制的所有指向节点的Data
只有next出现在”=“的左侧,链表的结构才会发生实质性改变。
insertFirst:在表头插入一个新的节点,时间复杂度为O(1)
deleteFirst:删除表头的节点,时间复杂度为O(1)
有了这两个方法,就可以用单链表来实现一个栈了
find:查找包含指定关键字的节点,由于需要遍历查找,平均需要查找N/2次,即O(N)
remove:删除包含指定关键字的节点,由于需要遍历查找,平均需要查找N/2次,即O(N)
public class LinkedList { public static void main(String[] args) { } class Data{ Object obj; Data next = null; Data(Object obj){ this.obj = obj; } } Data first = null; //头节点插入 public void insertFirst(Object obj){ Data data = new Data(obj); data.next = first; first = data; } //删除头节点 public Object deleteFirst()throws Exception{ if(first==null) throw new Exception("empty"); Data temp = first; first = first.next; return temp.obj; } //查找含有指定内容的节点 public Object find(Object obj)throws Exception{ if(first==null) throw new Exception("empty"); Data cur = first; while(cur!=null){ if(cur.obj.equals(obj)) return cur.obj; cur = cur.next; } return null; } //判断链表是否为空 public boolean isEmpty(){ return first==null; } //删除第一个含有指定元素的节点 public void remove(Object obj)throws Exception{ if(first==null) throw new Exception("empty"); if(first.obj.equals(obj)){ //单次 first = first.next; }else{ Data pre = first; Data cur = first.next; while(cur!=null){ if(cur.obj.equals(obj)){ pre.next = cur.next; break; } pre = cur; cur = cur.next; } } } //删除所有含有指定元素的节点 public void removeAll(Object obj)throws Exception{ if(first==null) throw new Exception("empty"); while(first.obj.equals(obj)){ first = first.next; } Data pre = first; Data cur = first.next; while(cur!=null){ if(cur.obj.equals(obj)){ pre.next = cur.next; pre = pre.next; cur = pre.next; //此时的pre.next跟上一行又不是一回事 continue; //跳过下面的迭代,继续下一次循环 } pre = cur; cur = cur.next; } } //遍历打印 public void display()throws Exception{ if(first == null) throw new Exception("your list is empty"); Data cur = first; while(cur!=null){ System.out.print(cur.obj.toString()+"->"); cur = cur.next; } System.out.println(); }}
执行结果1 -> 2 -> 3 -> 4 -> 2 -> 3 -> 4 -> 2 -> 4 -> null 4
双端链表
双端链表 不是 双向链表 ,双端只不过是保留最后节点的引用(last).
insertFirst:在表头插入一个新的节点,时间复杂度O(1)
insertLast:在表尾插入一个新的节点,时间复杂度O(1)
deleteFirst:删除表头的节点,时间复杂度O(1)
deleteLast::删除表尾的节点,由于只保存了表尾的节点,而没有保存表尾的前一个节点(单向,只能从前往后推),所以在删除表尾节点时需要遍历以找到表尾节点的前一个节点,需查找N-1次,也就是O(N)
用双端链表来实现一个队列
public class FirstLastList { private class Data{ private Object obj; private Data next = null; Data(Object x){ this.obj = x; } } Data first = null; Data last = null; public void insertFirst(Object obj){ Data data = new Data(obj); if(first==null) last=data; data.next = first; first = data; } public void insertLast(Object obj){ Data data = new Data(obj); if(first==null){ first = data; }else{ last.next = data; } last = data; } public Object deleteFirst()throws Exception{ if(first==null) throw new Exception("empty!"); Data temp = first; if(first.next==null) last = null; first = first.next; //if first.next = null that means first = null return temp.obj; } public void deleteLast()throws Exception{ if(first==null) throw new Exception("empty!"); if(first.next==null){ //single node scenario first = null; last = null; }else{ Data cur = first; while(cur.next!=null){ //stop by end if(cur.next==last){ last = cur; last.next = null; break; //这个break似乎没卵用啊?? 反正都到最后一个点了 加上也就少执行一次cur = cur.next } cur = cur.next; } } } public void display()throws Exception{ if(first == null) throw new Exception("your list is empty"); Data cur = first; while(cur!=null){ System.out.print(cur.obj.toString()+"->"); cur = cur.next; } System.out.println(); } public static void main(String[] args) throws Exception { FirstLastList fll = new FirstLastList(); fll.insertFirst(2); fll.insertFirst(1); fll.display(); fll.insertLast(3); fll.display(); fll.deleteFirst(); fll.display(); fll.deleteLast(); fll.display(); }}
执行结果 1 -> 2 -> 1 -> 2 -> 3 -> 2 -> 3 -> 2 ->
有序链表
单向链表在插入的时候排个序而已。
表的插入和删除平均需要比较N/2次,即O(N),但是获取最小数据项只需O(1),因为其始终处于表头,对频繁操作最小数据项的应用,可以考虑使用有序链表实现,如:优先级队列
public class SortedList { private class Data{ private Object obj; private Data next = null; Data(Object obj){ this.obj = obj; } } private Data first = null; public void insert(Object obj){ Data data = new Data(obj); Data pre = null; Data cur = first; while(cur!=null&&Integer.valueOf(data.obj.toString()).intValue()> Integer.valueOf(cur.obj.toString()).intValue()){ pre = cur; cur = cur.next; } if(pre==null) first = data; else pre.next = data; data.next = cur; } public Object deleteFirst()throws Exception{ if(first==null) throw new Exception("empty"); Data temp = first; first = first.next; return temp.obj; } public void display(){ if(first == null) System.out.println("empty"); System.out.print("first -> last : "); Data cur = first; while(cur != null){ System.out.print(cur.obj.toString() + " -> "); cur = cur.next; } System.out.print("\n"); } public static void main(String[] args) throws Exception{ SortedList sl = new SortedList(); sl.insert(80); sl.insert(2); sl.insert(100); sl.display(); System.out.println(sl.deleteFirst()); sl.insert(33); sl.display(); sl.insert(99); sl.display(); }}
执行结果first -> last : 2 -> 80 -> 100 -> 2first -> last : 33 -> 80 -> 100 -> first -> last : 33 -> 80 -> 99 -> 100 ->
- 【数据结构】单链表,双端链表,有序链表
- 数据结构:有序链表
- 有序链表的合并(数据结构---单链表)
- 数据结构整理_有序链表合并
- 数据结构之有序链表的归并
- 1465 数据结构:有序链表的合并
- java数据结构与算法-有序链表
- 数据结构--有序表查找
- 数据结构——将两个有序链表并为一个有序链表算法
- 数据结构 P31 算法实现 有序链表合并为有序链表
- Java单链表、双端链表、有序链表实现
- Java单链表、双端链表、有序链表实现
- Java单链表、双端链表、有序链表实现
- 数据结构-有序链表(基于简单链表)
- 【数据结构】单向有序链表---最水的代码
- 数据结构-用链表函数实现链表的有序合并
- 2119 数据结构实验之链表四:有序链表的归并
- 数据结构实验之链表六:有序链表的建立
- linux下vi命令大全
- Unity Animator混合树
- Cocos2d-x 3.x 图形学渲染系列总结
- debian系统下配置爬虫环境
- Android总结之链式调用(方法链)
- 【数据结构】单链表,双端链表,有序链表
- mysql view 视图
- 深拷贝与浅拷贝(Java)
- 123. Best Time to Buy and Sell Stock III(同小米风口的猪)
- 大牛级管家应用Trello:多平台“任务流”共享
- H5图片预览及上传(WEB前端)
- zookeeper集群为什么总是配置奇数个节点
- 浏览器端的缓存规则
- 几种常用加密算法比较