链表是由一系列结点(node)组成的,结点可以在运行时动态生成。链表有单向链表和双向链表两种结构,单向链表的每个结点包括两个部分:一个是存储数据元素的数据域,另一个是存储下一个结点地址的指针域。双向链表的每个结点包括三个部分:存储数据元素的数据域、存储下一个结点地址的指针域和存储上一个结点地址的指针域。
一、单向链表
单链表的特点是:节点的链接方向是单向的;相对于数组来说,单链表的的随机访问速度较慢,但是单链表删除/添加数据的效率很高。
单链表删除结点
单链表增加结点
二、双向链表
双向链表(双链表)是链表的一种。和单链表一样,双链表也是由节点组成,它的每个数据结点中都有两个指针,分别指向直接后继和直接前驱。所以,从双向链表中的任意一个结点开始,都可以很方便地访问它的前驱结点和后继结点。一般我们都构造双向循环链表。
双向链表删除结点
双向链表添加结点
三、手动实现LinkedList
java中的LinkedList是双向链表
1.定义结点
package cn.GTMStudio.MyConnection;
public class Node {
Node previous;//上一个结点
Node next;//下一个结点
Object element;//元素数据
public Node(Node previous, Node next, Object element) {
this.previous = previous;
this.next = next;
this.element = element;
}
public Node(Object element) {
this.element = element;
}
}
2.增加add方法
package cn.GTMStudio.MyConnection;
/**
* 添加add方法
* @author henrly
*/
@SuppressWarnings("all")
public class GTMLinkedList01 {
private Node first;//头指针
private Node last;//尾指针
private int size;//结点数
//
public void add(Object obj) {
Node node = new Node(obj);
if (first == null) {
//第一次调用时
first = node;
last = node;
} else {
node.previous = last;
node.next = null;
last.next = node;
last = node;
}
}
@Override
public String toString() {
StringBuilder sb = new StringBuilder();
sb.append("[");
Node temp = first;
while (temp != null) {
sb.append(temp.element + ",");
temp = temp.next;
}
sb.setCharAt(sb.length() - 1, ']');
return sb.toString();
}
public static void main(String[] args) {
GTMLinkedList01 list = new GTMLinkedList01();
list.add("a");
list.add("b");
list.add("c");
System.out.println(list);
}
}
3.增加get方法
链表的随机访问速度很慢,需要依次遍历,这里先判断索引与链表长度的一半,若小于则从头节点开始遍历,若大于则从尾结点开始遍历,这样就大大提高了效率。
Node temp = null;
if (index < (size >> 1)) {
temp = first;
for (int i = 0; i < index; i++) {
temp = temp.next;
}
} else {
temp = last;
for (int i = size - 1; i > index; i--) {
temp = temp.previous;
}
}
package cn.GTMStudio.MyConnection;
/**
* 自定义一个链表
* 增加get方法
*
* @author henrly
*/
@SuppressWarnings("all")
public class GTMLinkedList02 {
private Node first;
private Node last;
private int size;
public Object get(int index) {
if (index < 0 || index > size - 1) {
throw new RuntimeException("索引数字不合法:" + index);
}
Node temp = null;
if (index < (size >> 1)) {
temp = first;
for (int i = 0; i < index; i++) {
temp = temp.next;
}
} else {
temp = last;
for (int i = size - 1; i > index; i--) {
temp = temp.previous;
}
}
return temp.element;
}
//
public void add(Object obj) {
Node node = new Node(obj);
if (first == null) {
//第一次调用时
first = node;
last = node;
} else {
node.previous = last;
node.next = null;
last.next = node;
last = node;
}
size++;
}
@Override
public String toString() {
StringBuilder sb = new StringBuilder();
sb.append("[");
Node temp = first;
while (temp != null) {
sb.append(temp.element + ",");
temp = temp.next;
}
sb.setCharAt(sb.length() - 1, ']');
return sb.toString();
}
public static void main(String[] args) {
GTMLinkedList02 list = new GTMLinkedList02();
list.add("a");
list.add("b");
list.add("c");
list.add("d");
list.add("e");
list.add("f");
System.out.println(list);
System.out.println(list.get(1));
}
}
4.增加remove方法
package cn.GTMStudio.MyConnection;
/**
* 自定义一个链表
* 增加remove()方法
*
* @author henrly
*/
@SuppressWarnings("all")
public class GTMLinkedList03 {
private Node first;
private Node last;
private int size;
public void remove(int index) {
Node temp = getNode(index);
if (temp != null) {
Node up = temp.previous;
Node down = temp.next;
if (up != null) {
up.next = down;
}
if (down != null) {
down.previous = up;
}
if (index == 0) {
first = down;
}
if (index == size - 1) {
last = up;
}
size--;
}
}
public Object get(int index) {
Node temp = getNode(index);
return temp != null ? temp.element : null;
}
public Node getNode(int index) {
if (index < 0 || index > size - 1) {
throw new RuntimeException("索引数字不合法:" + index);
}
Node temp = null;
if (index < (size >> 1)) {
temp = first;
for (int i = 0; i < index; i++) {
temp = temp.next;
}
} else {
temp = last;
for (int i = size - 1; i > index; i--) {
temp = temp.previous;
}
}
return temp;
}
//
public void add(Object obj) {
Node node = new Node(obj);
if (first == null) {
//第一次调用时
first = node;
last = node;
} else {
node.previous = last;
node.next = null;
last.next = node;
last = node;
}
size++;
}
@Override
public String toString() {
StringBuilder sb = new StringBuilder();
sb.append("[");
Node temp = first;
while (temp != null) {
sb.append(temp.element + ",");
temp = temp.next;
}
sb.setCharAt(sb.length() - 1, ']');
return sb.toString();
}
public static void main(String[] args) {
GTMLinkedList03 list = new GTMLinkedList03();
list.add("a");
list.add("b");
list.add("c");
list.add("d");
list.add("e");
list.add("f");
System.out.println(list);
list.remove(2);
System.out.println(list);
list.remove(0);
System.out.println(list);
}
}
5. 增加插入方法
package cn.GTMStudio.MyConnection;
/**
* 自定义一个链表
* 增加插入方法
*
* @author henrly
*/
@SuppressWarnings("all")
public class GTMLinkedList04 {
private Node first;
private Node last;
private int size;
public void add(int index,Object obj){
Node newNode=new Node(obj);
Node temp=getNode(index);
if(temp!=null){
Node up=temp.previous;
up.next=newNode;
newNode.previous=up;
newNode.next=temp;
temp.previous=newNode;
}
}
public void remove(int index) {
Node temp = getNode(index);
if (temp != null) {
Node up = temp.previous;
Node down = temp.next;
if (up != null) {
up.next = down;
}
if (down != null) {
down.previous = up;
}
if (index == 0) {
first = down;
}
if (index == size - 1) {
last = up;
}
size--;
}
}
public Object get(int index) {
Node temp = getNode(index);
return temp != null ? temp.element : null;
}
public Node getNode(int index) {
if (index < 0 || index > size - 1) {
throw new RuntimeException("索引数字不合法:" + index);
}
Node temp = null;
if (index < (size >> 1)) {
temp = first;
for (int i = 0; i < index; i++) {
temp = temp.next;
}
} else {
temp = last;
for (int i = size - 1; i > index; i--) {
temp = temp.previous;
}
}
return temp;
}
//
public void add(Object obj) {
Node node = new Node(obj);
if (first == null) {
//第一次调用时
first = node;
last = node;
} else {
node.previous = last;
node.next = null;
last.next = node;
last = node;
}
size++;
}
@Override
public String toString() {
StringBuilder sb = new StringBuilder();
sb.append("[");
Node temp = first;
while (temp != null) {
sb.append(temp.element + ",");
temp = temp.next;
}
sb.setCharAt(sb.length() - 1, ']');
return sb.toString();
}
public static void main(String[] args) {
GTMLinkedList04 list = new GTMLinkedList04();
list.add("a");
list.add("b");
list.add("c");
list.add("d");
list.add("e");
list.add("f");
System.out.println(list);
list.add(3,"hhh");
System.out.println(list);
}
}
6.增加泛型
package cn.GTMStudio.MyConnection;
/**
* 自定义一个链表
* 增加小的封装、增加泛型
*
* @author henrly
*/
@SuppressWarnings("all")
public class GTMLinkedList05<E> {
private Node first;
private Node last;
private int size;
public void add(int index,E element){
Node newNode=new Node(element);
Node temp=getNode(index);
if(temp!=null){
Node up=temp.previous;
up.next=newNode;
newNode.previous=up;
newNode.next=temp;
temp.previous=newNode;
}
}
public void remove(int index) {
Node temp = getNode(index);
if (temp != null) {
Node up = temp.previous;
Node down = temp.next;
if (up != null) {
up.next = down;
}
if (down != null) {
down.previous = up;
}
if (index == 0) {
first = down;
}
if (index == size - 1) {
last = up;
}
size--;
}
}
public Object get(int index) {
Node temp = getNode(index);
return temp != null ? (E)temp.element : null;
}
private Node getNode(int index) {
if (index < 0 || index > size - 1) {
throw new RuntimeException("索引数字不合法:" + index);
}
Node temp = null;
if (index < (size >> 1)) {
temp = first;
for (int i = 0; i < index; i++) {
temp = temp.next;
}
} else {
temp = last;
for (int i = size - 1; i > index; i--) {
temp = temp.previous;
}
}
return temp;
}
//
public void add(E element) {
Node node = new Node(element);
if (first == null) {
//第一次调用时
first = node;
last = node;
} else {
node.previous = last;
node.next = null;
last.next = node;
last = node;
}
size++;
}
@Override
public String toString() {
StringBuilder sb = new StringBuilder();
sb.append("[");
Node temp = first;
while (temp != null) {
sb.append(temp.element + ",");
temp = temp.next;
}
sb.setCharAt(sb.length() - 1, ']');
return sb.toString();
}
public static void main(String[] args) {
GTMLinkedList05<String > list = new GTMLinkedList05<>();
list.add("a");
list.add("b");
list.add("c");
list.add("d");
list.add("e");
list.add("f");
System.out.println(list);
list.add(3,"hhh");
System.out.println(list);
}
}