链表 真正的动态数据结构
最简单的动态数据结构
更深入的理解引用(或者指针)
更深入理解递归
辅助其他数据结构
数组
链表
/**
* @Author: eastlong
* @Date 2020/3/14
* @function:
**/
public class LinkedList<E> {
// 设计成私有的内部类
private class Node{
public E e;
public Node next;
public Node(E e,Node next){
this.e = e;
this.next = next;
}
public Node(E e){
this(e,null);
}
public Node(){
this(null, null);
}
}
}
// 在链表头添加新的元素e
public void addFirst(E e){
Node node = new Node(e);
node.next = head;
head = node;
// head = new Node(e,head); // 上述三个步骤可以浓缩为一句代码
size ++; // 维护size
}
// 在index为2的位置添加新的元素e
// 在链表操作中不是一个常用的操作,练习用
public void add(int index, E e) {
if (index < 0 || index > size)
throw new IllegalArgumentException("Add failed,Illegal index.");
if (index == 0) {
addFirst(e);
}else {
Node prev = head;
for(int i = 0; i < index -1; i ++){
prev = prev.next; // prev 右移动
}
Node node = new Node(e);
node.next = prev.next;
prev.next = node;
// 上述三个步骤可以浓缩为一句代码
prev.next = new Node(e,prev.next);
size ++;
}
}
// 在链表的末尾添加元素
public void addLast(E e){
add(size,e);
}
代码做如下修改
package com.betop.datastruct.链表;
/**
* @Author: eastlong
* @Date 2020/3/14
* @function:
**/
public class LinkedList<E> {
// 设计成私有的内部类
private class Node {
public E e;
public Node next;
public Node(E e, Node next) {
this.e = e;
this.next = next;
}
public Node(E e) {
this(e, null);
}
public Node() {
this(null, null);
}
public String toString() {
return e.toString();
}
}
private Node dummyHead;
private int size;
public LinkedList() {
dummyHead = new Node(null, null);// 虚拟头结点
size = 0;
}
// 获取链表的中元素的个数
public int getSize() {
return size;
}
// 返回链表是否为空
public boolean isEmpty() {
return size == 0;
}
// 在index为2的位置添加新的元素e
// 在链表操作中不是一个常用的操作,练习用
public void add(int index, E e) {
if (index < 0 || index > size)
throw new IllegalArgumentException("Add failed,Illegal index.");
Node prev = dummyHead;
for (int i = 0; i < index; i++) // 从dummyHead开始遍历,遍历index次
prev = prev.next; // prev 右移动
// Node node = new Node(e);
// node.next = prev.next;
// prev.next = node;
// 上述三个步骤可以浓缩为一句代码
prev.next = new Node(e, prev.next);
size++;
}
// 在链表头添加新的元素e
public void addFirst(E e) {
add(0, e);
}
// 在链表的末尾添加元素
public void addLast(E e) {
add(size, e);
}
}
【总结】虚拟头结点的引入,使得代码更加简洁高效。
// 获得链表第index(0-based)位置的元素
// 在链表操作中不是一个常用的操作,练习用
public E get(int index){
if(index < 0 || index > size)
throw new IllegalArgumentException("Add failed,Illegal index.");
Node cur = dummyHead.next; // 从0开始
for(int i=0; i< index;i++)
cur = cur.next;
return cur.e;
}
// 修改链表第index(0-based)位置的元素
// 在链表操作中不是一个常用的操作,练习用
public void set(int index,E e){
if(index < 0 || index > size)
throw new IllegalArgumentException("Set failed,Illegal index.");
Node cur = dummyHead.next;
for(int i=0;i<index;i++) // 遍历index次
cur = cur.next;
cur.e = e;
}
// 查询链表中是否有元素e
public boolean contains(E e){
Node cur = dummyHead.next;
while (cur != null) { // 表示当前结点是有效结点
if(cur.e.equals(e))
return true;
cur = cur.next;
}
return false;
}
@Override
public String toString() {
StringBuilder res = new StringBuilder();
Node cur = dummyHead.next;
while (cur != null) {
res.append(cur + "->");
cur = cur.next;
}
res.append("NULL");
return res.toString();
}
测试
/**
* @Author: eastlong
* @Date 2020/3/14
* @function:
**/
public class Main {
public static void main(String[] args) {
LinkedList<Integer> linkedList = new LinkedList<>();
for (int i = 0; i < 5; i++) {
linkedList.addFirst(i);
System.out.println(linkedList);
}
linkedList.add(2, 666);
System.out.println(linkedList);
}
}
// 删除链表索引为index(0-based)位置的元素,返回删除的元素
// 在链表操作中不是一个常用的操作,练习用
public E remove(int index) {
if (index < 0 || index >= size)
throw new IllegalArgumentException("remove failed,Illegal index.");
Node pre = dummyHead; // 要找到被删除元素的前一个元素,因此从dummyHead开始
for (int i = 0; i < index; i++)
pre = pre.next;
Node retNode = pre.next;// 被删除的元素
pre.next = retNode.next;
retNode.next = null;
size --;
return retNode.e;
}
// 删除第一个元素
public E removeFirst() {
return remove(0);
}
// 删除最后一个元素
public E removeLast() {
return remove(size - 1);
}
添加操作
删除操作
修改操作
查找操作
总结
package com.betop.datastruct.链表;
import com.betop.datastruct.队列.Queue;
/**
* @Author: eastlong
* @Date 2020/3/15
* @function: 链表实现队列
**/
public class LinkedListQueue<E> implements Queue<E> {
// 设计成私有的内部类
private class Node {
public E e;
public Node next;
public Node(E e, Node next) {
this.e = e;
this.next = next;
}
public Node(E e) {
this(e, null);
}
public Node() {
this(null, null);
}
public String toString() {
return e.toString();
}
}
private Node head,tail;
private int size;
public LinkedListQueue(){
head = null;
tail = null;
size = 0;
}
@Override
public int getSize() {
return size;
}
@Override
public boolean isEmpty() {
return size == 0;
}
@Override
public void enqueue(E e) { // 入队,从队尾插入
if(tail == null){ // 空队列
tail = new Node(e);
head = tail;
}
else {
tail.next = new Node(e);
tail = tail.next;
}
size ++;
}
@Override
public E dequeue() { //出队操作,队列从队首出队
if(isEmpty())
throw new IllegalArgumentException("Cannot dequeue from an empty queue.");
Node retNode = head;
head = head.next;
retNode.next = null;
if(head == null) // 如果head为null,则tail为null;否则没有变化
tail = null;
size --;
return retNode.e;
}
@Override
public E front() {
if(isEmpty()){
throw new IllegalArgumentException("Queue is empty.");
}
return null;
}
@Override
public String toString(){
StringBuilder res = new StringBuilder();
res.append("Queue front:");
Node cur = head;
while (cur != null){
res.append(cur + "->");
cur = cur.next;
}
res.append("NULL tail");
return res.toString();
}
public static void main(String[] args) {
LinkedListQueue<Integer> queue = new LinkedListQueue<>();
for(int i=0;i<10;i++){
queue.enqueue(i);
System.out.println(queue);
if(i%3==2){
queue.dequeue();
System.out.println(queue);
}
}
}
}
内容来源于网络,如有侵权,请联系作者删除!