线性表是一种简单的数据类型,它是具有相同类型的n个数据元素组成的有限序列。形如如A0,A1,...,An-1。大小为0的表为空表,称Ai后继Ai-1,并称Ai-1前驱Ai

printList打印出表元素,makeEmpty置空表,find返回某一项首次出现的位置,insert和remove一般是从表的某个位置插入和删除某个元素;而findKth则返回某个位置上的元素,next和previous会取一个位置作为参数返回前驱元和后继元的值。

表的数组实现

对表的所有操作都可以通过数组实现。数组的存储示意图如下:

这种存储结构的特点是:数据是连续的,随机访问速度快。printList以线性时间执行,findKth操作则话费常数时间。对于插入和删除来说效率是比较低下的,最坏情况下,在位置0的插入需要将所有元素向后移动一个位置。

基于数组的链表实现:

public class MyArrayList<T> implements Iterable<T>{

    private static final int DEFAULT_CAPACITY=10;
private int size;
private T[] items; public MyArrayList() {
doClear();
} public void clear() {
doClear();
} public int size() {
return size;
} public boolean isEmpty() {
return size == 0;
} public void trimToSize() {
ensureCapacity(size);
} public boolean add(T x) {
add(size, x);
return true;
} public void add(int idx, T x) {
if (items.length == size) {
ensureCapacity(size * 2 + 1);
}
for (int i = size; i > idx; i--) {
items[i] = items[i - 1];
}
items[idx] = x;
size++;
} public T remove(int idx) {
T removedItem = items[idx];
for (int i = idx; i < size - 1; i++) {
items[i] = items[i + 1];
}
size--;
return removedItem;
} private void doClear() {
size = 10;
ensureCapacity(DEFAULT_CAPACITY);
} private void ensureCapacity(int newCapacity) {
if (newCapacity < size) {
return;
}
T[] old = items;
items = (T[]) new Object[newCapacity];
for (int i = 0; i < size; i++) {
items[i] = old[i];
}
} public Iterator<T> iterator() {
return new ArrayListIterator();
} private class ArrayListIterator implements Iterator<T> {
private int current = 0; @Override
public boolean hasNext() {
return current < size;
} @Override
public T next() {
if (!hasNext())
throw new NoSuchElementException();
return items[current++];
} public void remove() {
MyArrayList.this.remove(--current);
}
}
}

单链表

当需要对表进行频繁的插入删除操作时,数组的实现方式就显得效率过低了。链表由一些列节点组成,这些节点不必在内存中相连。每一个节点均含有表元素和到包含该元素后继元的节点的链。单链表的存储示意图如下:

remove操作只需要移动next引用即可实现:

insert方法需要先添加一个节点,然后执行两次引用的调整:

单链表的特点:节点的链接方向是单向的;相对于数组,单链表的随机访问速度较慢,添加、删除效率较高

双向链表

双向链表与单向链表结构相似,由数据元素和两个链组成,这两个链分别指向该节点的前驱和后继。一般构建为双向循环链表,即最后一个节点的next链指向链表的第一个元素,第一个节点的previous链指向链表的最后一个元素。存储结构如下:

双向链表删除:

双向链表的添加就是删除的一个逆过程,不再画图了。

双向链表实现:

public class DoubleLink<T> {
// 表头
private Node<T> head;
// 节点数
private int count; private class Node<T> {
public Node prev; // 前节点
public Node next; // 后节点
public T value; public Node(T value, Node prev, Node next) {
this.prev = prev;
this.next = next;
this.value = value;
}
} public DoubleLink() {
// 创建表头
head = new Node<>(null, null, null);
head.prev = head.next = head;
count = 0;
} // 节点数
public int size() {
return count;
} // 判断表是否为空
public boolean isEmpty() {
return count == 0;
} // 获取第index位置的节点
private Node<T> getNode(int index) {
if (index < 0 || index >= count) {
throw new IndexOutOfBoundsException();
}
// 正向查找
if (index <= count / 2) {
Node<T> node = head.next;
for (int i = 0; i < index; i++) {
node = node.next;
}
return node;
}
// 反向查找
Node<T> rnode = head.prev;
int rindex = count - index - 1;
for (int j = 0; j < rindex; j++) {
rnode = rnode.prev;
}
return rnode;
} // 获取第index位置节点的值
public T get(int index) {
return getNode(index).value;
} // 将节点插入到index位置
public void insert(int index, T t) {
if (index == 0) {
Node node = new Node(t, head, head.next);
head.next.prev = node;
head.next = node;
count++;
return;
}
Node<T> inode = getNode(index);
// 创建新节点
Node<T> newNode = new Node<>(t, inode.prev, inode);
inode.prev.next = newNode;
inode.next = newNode;
return;
} // 删除节点
public Node<T> delete(int index) {
Node<T> delNode = getNode(index);
delNode.prev.next = delNode.next;
delNode.next.prev = delNode.prev;
count--;
return delNode;
}
}

Java数据结构与算法(1):线性表的更多相关文章

  1. Java数据结构和算法 - 哈希表

    Q: 如何快速地存取员工的信息? A: 假设现在要写一个程序,存取一个公司的员工记录,这个小公司大约有1000个员工,每个员工记录需要1024个字节的存储空间,因此整个数据库的大小约为1MB.一般的计 ...

  2. 【数据结构与算法】线性表操作(C++)

    #include <stdio.h> #define maxSize 100 //定义整型常量maxSize值为100 /*顺序表的结构体定义*/ typedef struct SqLis ...

  3. 【数据结构与算法】线性表操作(C语言)

    #include <stdio.h> #include <stdlib.h> #define OK 1 #define NO 0 #define MAXSIZE 20 type ...

  4. Java数据结构和算法(一)线性结构

    Java数据结构和算法(一)线性结构 数据结构与算法目录(https://www.cnblogs.com/binarylei/p/10115867.html) 线性表 是一种逻辑结构,相同数据类型的 ...

  5. Java数据结构和算法(一)线性结构之单链表

    Java数据结构和算法(一)线性结构之单链表 prev current next -------------- -------------- -------------- | value | next ...

  6. 【Java数据结构学习笔记之二】Java数据结构与算法之栈(Stack)实现

      本篇是java数据结构与算法的第2篇,从本篇开始我们将来了解栈的设计与实现,以下是本篇的相关知识点: 栈的抽象数据类型 顺序栈的设计与实现 链式栈的设计与实现 栈的应用 栈的抽象数据类型   栈是 ...

  7. java数据结构与算法之栈(Stack)设计与实现

    本篇是java数据结构与算法的第4篇,从本篇开始我们将来了解栈的设计与实现,以下是本篇的相关知识点: 栈的抽象数据类型 顺序栈的设计与实现 链式栈的设计与实现 栈的应用 栈的抽象数据类型 栈是一种用于 ...

  8. Java数据结构和算法 - 高级排序

    希尔排序 Q: 什么是希尔排序? A: 希尔排序因计算机科学家Donald L.Shell而得名,他在1959年发现了希尔排序算法. A: 希尔排序基于插入排序,但是增加了一个新的特性,大大地提高了插 ...

  9. Java数据结构和算法(一)散列表

    Java数据结构和算法(一)散列表 数据结构与算法目录(https://www.cnblogs.com/binarylei/p/10115867.html) 散列表(Hash table) 也叫哈希表 ...

随机推荐

  1. 标准库path源码解读

    先看标准库 作用:关于路径的一些实用操作 https://github.com/golang/go/blob/master/src/path/path.go 源码地址 func IsAbs func ...

  2. [七月挑选]使用hexo建立主题,并发布到github

    title: 使用hexo建立主题,并发布到github 根据hexo官网的概述和hexo官网的建站,搭建最开始的hexo博客. 1.环境预先安装好node.js和git 2.npm安装hexo: $ ...

  3. 为啥要使用Hessian

    1.为啥要使用Hessian? 有需求就有市场,挨踢界也是一样,想要实现远程调用,Hessian就应运而生. 场景:有一个后台系统,基本上所有的用户管理都在这个系统里操作,其中有一个方法是添加用户的方 ...

  4. How Does Caching Work in AFNetworking? : AFImageCache & NSUrlCache Explained

    http://blog.originate.com/blog/2014/02/20/afimagecache-vs-nsurlcache/

  5. Django之modles 多对多创建第三张表

    一.第一种:纯自动创建第三张表 纯自动 class Book(models.Model): title = models.CharField(max_length=32) price = models ...

  6. Git Fast Forward 和 no fast foward

    如果执行了 Fast Forward,开发者根本不会看到这个分支,就像在 master 直接 commit 一样.

  7. IDEA开发初始化设置

    一.基本设置 1. 自动生成 serialVersionUID 的设置 2. 设置文件注释 3. 隐藏项目文件(夹) .git;.gitignore;.idea;.idea/.;.mvn;mvnw;m ...

  8. springcloud 配置actuator

    pom.xml <!--Spring Boot Actuator,感应服务端变化--> <dependency> <groupId>org.springframew ...

  9. RAC heartbeat 心跳机制

    世界上最遥远的距离,不是生与死.而是我们同一个集群的两个节点,你却听不到我的心跳. 必要性:维持集群的⼀致性RAC⼼跳机制 – 集群⼼跳基本机制:1.确定节点和节点间的连通性,达到彼此了解2.⽤共享的 ...

  10. wepy-开发总结(功能点)

    开发小程序中,遇到的wepy的几点坑,记录一下; 更详细的项目总结记录请见我的个人博客:https://fanghongliang.github.io/ 1.定时器: 在页面中有需要用到倒计时或者其他 ...