学习数据结构与算法之美记录,之前已经看数据结构与算法视频过了三遍,每次看完就结束,这次一定学习+动手,后续每天或每周抽出时间做题保持学习状态
一段连续存储的空间,可以通过下标定位到对应位置的线性结构
由多个节点组成,每个节点有一或两个指针指向其它节点,构成的线性结构。
种类:
package com.zsl.datastructalgorithm.date20220625;
import lombok.Data;
/**
* 实现单链表反转
*
* @Author zsl
* @Date 2022/6/25 22:22
* @Email 249269610@qq.com
*/
public class SingleLinkedList<T> {
// 头
private Node<T> head;
// 尾
private Node<T> tail;
// 大小
private int size = 0;
/**
* 新增元素
*/
public void add(T obj) {
Node<T> node = new Node<>();
node.obj = obj;
if (head == null) {
head = node;
tail = node;
size = 1;
} else {
tail.next = node;
tail = node;
++size;
}
}
/**
* 获取索引元素
*/
public T get(int index) {
if (size == 0) {
return null;
}
T obj = null;
if (index < size) {
Node<T> currNode = head;
for (int i = 0; i < index; i++) {
currNode = currNode.next;
}
obj = currNode.obj;
}
return obj;
}
/**
* 移除索引元素
*/
public boolean remove(int index) {
// 边界处理(空链表、索引无效)
if (size == 0 || index >= size || index < 0) {
return false;
}
// 特殊处理
if (index == 0) {
if (size == 1) {
head = null;
tail = null;
return true;
} else {
head = head.next;
}
}
// 查找索引元素
Node<T> prevNode = null;
Node<T> currNode = head;
for (int i = 0; i < index; i++) {
prevNode = currNode;
currNode = currNode.next;
}
// 移除节点
assert prevNode != null;
prevNode.next = currNode.next;
// 末尾处理
if (index == --size) {
tail = prevNode;
}
return true;
}
/**
* 反转
* 遍历一遍,缺点:反转过程中get(index)会出错
*/
public void reverse() {
if (size < 2) {
return;
}
tail = head;
Node<T> currNode = head;
Node<T> nextNode = currNode.next;
head.next = null;
for (int i = 0; i < size - 1; i++) {
currNode = nextNode;
nextNode = nextNode.next;
currNode.next = head;
head = currNode;
}
}
@Override
public String toString() {
return "SingleList{" +
"head=" + head +
", tail=" + tail +
", size=" + size +
'}';
}
/**
* 节点
*/
@Data
public static class Node<T> {
private T obj;
private Node<T> next;
}
public static void main(String[] args) {
SingleLinkedList<Integer> list = new SingleLinkedList<>();
for (int i = 0; i < 10; i++) {
list.add(i);
}
System.out.println(list);
list.remove(4);
System.out.println(list);
list.reverse();
System.out.println(list);
}
}
正确写出链表代码六个技巧:
LIFO后进先出,一种操作受限的线性表数据结构
种类
package com.zsl.datastructalgorithm.date20220626;
/**
* @Author zsl
* @Date 2022/6/26 10:33
* @Email 249269610@qq.com
*/
public class Stack {
// 数组元素
private Integer[] elements;
// 容量
private final int capacity;
// 当前栈存储元素个数
private int size;
public Stack(int capacity) {
this.elements = new Integer[capacity];
this.capacity = capacity;
this.size = 0;
}
/**
* 入栈
*/
public boolean push(Integer element) {
// 边界处理
if (size == capacity) {
return false;
}
elements[size++] = element;
return true;
}
/**
* 出栈
*/
public Integer pop() {
// 边界处理
if (size == 0) {
return null;
}
return elements[--size];
}
/**
* 查看栈顶元素
*/
public Integer peek() {
// 边界处理
if (size == 0) {
return null;
}
return elements[size - 1];
}
public static void main(String[] args) {
Stack stack = new Stack(10);
for (int i = 0; i < 16; i++) {
System.out.println(String.format("%02d:push number: %d, 结果:%s", i, i, stack.push(i)));
}
for (int i = 0; i < 16; i++) {
Integer pop = stack.pop();
System.out.println(String.format("%02d:pop 结果:%d", i, pop));
}
}
}
FIFO先进先出,也是一种操作受限的线性表数据结构
种类 --> 存储形式
package com.zsl.datastructalgorithm.date20220626;
/**
* 素组循环队列,存储容量为 capacity - 1;达到上限直接抛弃
*
* @author zsl
* @date 2022/6/26 18:46
* @email 249269610@qq.com
*/
public class ArrayQueue {
// 元素数组
private Integer[] elements;
// 头
private int head;
// 尾
private int tail;
// 容量
private final int capacity;
public ArrayQueue(int capacity) {
this.elements = new Integer[capacity];
this.head = 0;
this.tail = 0;
this.capacity = capacity;
}
/**
* 入队
*/
public boolean enqueue(Integer element) {
// 判断队列是否有空闲
if (tail + 1 == head) return false;
elements[tail++] = element;
// 边界处理
if (tail == capacity) tail = 0;
return true;
}
/**
* 出队
*/
public Integer dequeue() {
// 判断是否有元素
if (tail == head) return null;
Integer element = elements[head++];
// 边界处理
if (head == capacity) head = 0;
return element;
}
public static void main(String[] args) {
ArrayQueue arrayQueue = new ArrayQueue(10);
for (int i = 0; i < 16; i++) {
System.out.println(String.format("%02d:enqueue element=%02d, 结果 %s", i, i, arrayQueue.enqueue(i)));
if (i == 7) {
System.out.println(String.format("%02d:dequeue ,结果 %s", i, arrayQueue.dequeue()));
}
if (i == 14) {
System.out.println(String.format("%02d:dequeue ,结果 %s", i, arrayQueue.dequeue()));
}
}
for (int i = 0; i < 14; i++) {
System.out.println(String.format("%02d:dequeue ,结果 %s", i, arrayQueue.dequeue()));
}
}
}
扩展