Java单链表、双端链表、有序链表实现
单链表:
insertFirst:在表头插入一个新的链接点,时间复杂度为O(1)
deleteFirst:删除表头的链接点,时间复杂度为O(1)
有了这两个方法,就可以用单链表来实现一个栈了,见http://blog.csdn.net/a19881029/article/details/22579759
find:查找包含指定关键字的链接点,由于需要遍历查找,平均需要查找N/2次,即O(N)
remove:删除包含指定关键字的链接点,由于需要遍历查找,平均需要查找N/2次,即O(N)
- public class LinkedList {
- private class Data{
- private Object obj;
- private Data next = null;
- Data(Object obj){
- this.obj = obj;
- }
- }
- private 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("LinkedList is empty!");
- Data cur = first;
- while(cur != null){
- if(cur.obj.equals(obj)){
- return cur.obj;
- }
- cur = cur.next;
- }
- return null;
- }
- public void remove(Object obj) throws Exception{
- if(first == null)
- throw new Exception("LinkedList is 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;
- }
- pre = cur;
- cur = cur.next;
- }
- }
- }
- public boolean isEmpty(){
- return (first == null);
- }
- public void display(){
- if(first == null)
- System.out.println("empty");
- 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 {
- LinkedList ll = new LinkedList();
- ll.insertFirst(4);
- ll.insertFirst(3);
- ll.insertFirst(2);
- ll.insertFirst(1);
- ll.display();
- ll.deleteFirst();
- ll.display();
- ll.remove(3);
- ll.display();
- System.out.println(ll.find(1));
- System.out.println(ll.find(4));
- }
- }
- 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)
有了这几个方法就可以用双端链表来实现一个队列了,http://blog.csdn.net/a19881029/article/details/22654121
- public class FirstLastList {
- private class Data{
- private Object obj;
- private Data next = null;
- Data(Object obj){
- this.obj = obj;
- }
- }
- private Data first = null;
- private 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;
- return temp.obj;
- }
- public void deleteLast() throws Exception{
- if(first == null)
- throw new Exception("empty");
- if(first.next == null){
- first = null;
- last = null;
- }else{
- Data temp = first;
- while(temp.next != null){
- if(temp.next == last){
- last = temp;
- last.next = null;
- break;
- }
- temp = temp.next;
- }
- }
- }
- public void display(){
- if(first == null)
- System.out.println("empty");
- 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 {
- 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 ->
有序链表:链表中的数据按从小到大排列
- 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 ->
- 2
- first -> last : 33 -> 80 -> 100 ->
- first -> last : 33 -> 80 -> 99 -> 100 ->
表的插入和删除平均需要比较N/2次,即O(N),但是获取最小数据项只需O(1),因为其始终处于表头,对频繁操作最小数据项的应用,可以考虑使用有序链表实现,如:优先级队列
和数组相比,链表的优势在于长度不受限制,并且在进行插入和删除操作时,不需要移动数据项,故尽管某些操作的时间复杂度与数组想同,实际效率上还是比数组要高很多
劣势在于随机访问,无法像数组那样直接通过下标找到特定的数据项
Java单链表、双端链表、有序链表实现的更多相关文章
- Java数据结构——用双端链表实现队列
//================================================= // File Name : LinkQueue_demo //---------------- ...
- java数据结构-09双端队列
一.相关概念: (Deque)双端队列能够在队头.队尾进行添加.删除等操作 二.接口设计: 三.代码实现 public class Deque<E> { private List< ...
- C++单链表反转、两有序链表合并仍有序
1 #include<iostream> 2 3 struct Node 4 { 5 int data; 6 Node *next; 7 }; 8 9 typedef struct Nod ...
- java数据结构——单链表、双端链表、双向链表(Linked List)
1.继续学习单链表,终于摆脱数组的魔爪了,单链表分为数据域(前突)和引用域(指针域)(后继),还有一个头结点(就好比一辆火车,我们只关心火车头,不关心其它车厢,只需知晓车头顺藤摸瓜即可),头结点没有前 ...
- JAVA基础——链表结构之双端链表
双端链表:双端链表与传统链表非常相似.只是新增了一个属性-即对最后一个链结点的引用 如上图所示:由于有着对最后一个链结点的直接引用.所以双端链表比传统链表在某些方面要方便.比如在尾部插入一个链结点.双 ...
- Java实现 LeetCode 21 合并两个有序链表
21. 合并两个有序链表 将两个有序链表合并为一个新的有序链表并返回.新链表是通过拼接给定的两个链表的所有节点组成的. 示例: 输入:1->2->4, 1->3->4 输出:1 ...
- c# 有序链表合并 链表反转
using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.T ...
- 算法练习之合并两个有序链表, 删除排序数组中的重复项,移除元素,实现strStr(),搜索插入位置,无重复字符的最长子串
最近在学习java,但是对于数据操作那部分还是不熟悉 因此决定找几个简单的算法写,用php和java分别实现 1.合并两个有序链表 将两个有序链表合并为一个新的有序链表并返回.新链表是通过拼接给定的两 ...
- 代码题(14)— 合并有序链表、数组、合并K个排序链表
1.21. 合并两个有序链表 将两个有序链表合并为一个新的有序链表并返回.新链表是通过拼接给定的两个链表的所有节点组成的. 示例: 输入:1->2->4, 1->3->4 输出 ...
- leecode刷题(23)-- 合并两个有序链表
leecode刷题(23)-- 合并两个有序链表 合并两个有序链表 将两个有序链表合并为一个新的有序链表并返回.新链表是通过拼接给定的两个链表的所有节点组成的. 示例: 输入:1->2-> ...
随机推荐
- 传智168期JavaEE就业班 day01-html
* HTML * HTML: HyperText Markup Language 超文本标记语言. * HTML是最基础的网页语言. * HTML的代码都是由标签所组成. * HTML的基本格式 &l ...
- Convention插件
考虑使用COnvention插件可以进行零配置而且插件进行很多规范的约定也可以对开发合作当中按着它相应的规律开发..感觉也挺方便管理的.下面简单介绍它的使用. 首先我们需要使用到的jar包: Java ...
- OC基础--OC中的类方法和对象方法
PS:个人感觉跟C#的静态方法和非静态方法有点类似,仅仅是有点类似.明杰老师说过不要总跟之前学过的语言做比较,但是个人觉得,比较一下可以加深印象吧.重点是自己真的能够区分开! 一.OC中的对象方法 1 ...
- offsetLeft, offsetTop以及postion().left , postion().top有神马区别
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/ ...
- 旅行(Dijkstra)问题
问题:输入: 输入数据有多组,每组的第一行是三个整数T,S和D,表示有T条路,和草儿家相邻的城市的有S个,草儿想去的地方有D个: 接着有T行,每行有三个整数a,b,time,表示a,b城市之间的车 ...
- C++ STL之stack
因为总用vector,却忘记了有stack,今天用到栈顶的值才想起来,说起来stack很方便,也很容易用,看下边例子: #include<stack> #include<iostre ...
- memcache 开发版
memcache安装,如果是用xampp,一定要下载开发版本 解压开发包,将其中的include目录复制到应用的lampp目录下 tar -zxvf xampp-linux-devel-1.7.2.t ...
- 织梦DedeCms网站更换域名后文章图片路径批量修改
因为织梦上传图片用的是绝对地址,如果域名更换后,之前发布的文章的图片URL是不会跟着改变的,所以我们需要把旧域名替换成新的域名,方法很简单,有一段SQL语句更新一下文章正文内容就行. 复制下面SQL语 ...
- zencart资源
http://www.zen-cart.cn/ http://www.ezencart.com/
- HTTP协议详解(一直在用可是这篇太好了转一下)
引言 HTTP是一个属于应用层的面向对象的协议,由于其简捷.快速的方式,适用于分布式超媒体信息系统.它于1990年提出,经过几年的使用与发展,得到不断地完善和扩展.目前在WWW中使用的是HTTP/1. ...