目录
1.链表
1.1概述
一种线性数据结构,数据存储在 Node 节点中
public class LinkedList<E> {
private class Node{
public E e;
public Node next;
}
}
1.2在链表中添加元素
public class LinkedList<E> {
private class Node{
/**
* 链表中的元素e
*/
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);
}
@Override
public String toString() {
return e.toString();
}
}
/**
* 头节点
*/
private Node head;
/**
* 实际元素个数
*/
int size;
public LinkedList(){
head = null;
size = 0;
}
/**
* 获取链表中的元素个数
* @return
*/
public int getSize(){
return size;
}
/**
* 返回链表是否为空
*/
public Boolean isEmpty(){
return size == 0;
}
/**
* 在链表头添加新元素e
* @param e
*/
public void addFirst(E e){
head = new Node(e,head);
size ++;
}
/**
* index 位置新增元素 e
* @param index
* @param e
*/
public void add(int index,E e){
if (index > size){
throw new RuntimeException("add fail.index iLLegal");
}
if (index == 0){
addFirst(e);
}else {
Node prev = head;
// 找到前一个节点的位置
for (int i = 0; i < index - 1; i++) {
prev = prev.next;
}
prev.next = new Node(e,prev.next);
size++;
}
}
/**
* 在链表末尾添加新的元素e
* @param e
*/
public void addLast(E e){
add(size,e);
}
}
1.3使用链表的虚拟头节点
public class LinkedList<E> {
private class Node {
/**
* 链表中的元素e
*/
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);
}
@Override
public String toString() {
return e.toString();
}
}
/**
* 头节点
*/
private Node dummyHead;
/**
* 实际元素个数
*/
int size;
public LinkedList() {
dummyHead = new Node(null, null);
size = 0;
}
/**
* 获取链表中的元素个数
*
* @return
*/
public int getSize() {
return size;
}
/**
* 返回链表是否为空
*/
public Boolean isEmpty() {
return size == 0;
}
/**
* index 位置新增元素 e
*
* @param index
* @param e
*/
public void add(int index, E e) {
if (index > size) {
throw new RuntimeException("add fail.index iLLegal");
}
Node prev = dummyHead;
// 找到前一个节点的位置
for (int i = 0; i < index; i++) {
prev = prev.next;
}
prev.next = new Node(e, prev.next);
size++;
}
/**
* 在链表头添加新元素e
*
* @param e
*/
public void addFirst(E e) {
add(0,e);
}
/**
* 在链表末尾添加新的元素e
*
* @param e
*/
public void addLast(E e) {
add(size, e);
}
}
1.4遍历链表,查询和修改
public class LinkedList<E> {
private class Node {
/**
* 链表中的元素e
*/
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);
}
@Override
public String toString() {
return e.toString();
}
}
/**
* 头节点
*/
private Node dummyHead;
/**
* 实际元素个数
*/
int size;
public LinkedList() {
dummyHead = new Node(null, null);
size = 0;
}
/**
* 获取链表中的元素个数
*
* @return
*/
public int getSize() {
return size;
}
/**
* 返回链表是否为空
*/
public Boolean isEmpty() {
return size == 0;
}
/**
* index 位置新增元素 e
*
* @param index
* @param e
*/
public void add(int index, E e) {
if (index > size) {
throw new RuntimeException("add fail.index iLLegal");
}
Node prev = dummyHead;
// 找到前一个节点的位置
for (int i = 0; i < index; i++) {
prev = prev.next;
}
prev.next = new Node(e, prev.next);
size++;
}
/**
* 在链表头添加新元素e
*
* @param e
*/
public void addFirst(E e) {
add(0, e);
}
/**
* 在链表末尾添加新的元素e
*
* @param e
*/
public void addLast(E e) {
add(size, e);
}
/**
* 获取链表中第index位置的元素
*
* @param index
* @return
*/
public E get(int index) {
if (index < 0 || index >= size) {
throw new RuntimeException("add fail.index iLLegal");
}
Node cur = dummyHead.next;
for (int i = 0; i < index; i++) {
cur = cur.next;
}
return cur.e;
}
/**
* 获取链表中第1个元素
*
* @return
*/
public E getFirst() {
return get(0);
}
/**
* 获取链表中最后一个元素
*
* @return
*/
public E getLast() {
return get(size - 1);
}
/**
* 修改index位置的元素为e
*
* @return
*/
public void set(int index, E e) {
if (index < 0 || index >= size) {
throw new RuntimeException("set fail.index iLLegal");
}
Node cur = dummyHead.next;
for (int i = 0; i < index; i++) {
cur = cur.next;
}
cur.e = e;
}
/**
* 链表中是否包含元素e
*
* @param e
* @return
*/
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();
}
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,66666);
System.out.println(linkedList);
}
}
1.5链表中删除元素
/**
* 删除index位置的索引
* @param index
* @return
*/
public E remove(int index){
if (index < 0 || index >= size) {
throw new RuntimeException("remove fail.index iLLegal");
}
Node prev = dummyHead;
for (int i = 0; i < index; i++) {
prev = prev.next;
}
Node retNode = prev.next;
prev.next = retNode.next;
retNode.next = null;
size --;
return retNode.e;
}
/**
* 删除链表中的第一个元素,返回删除元素
* @return
*/
public E removeFirst(){
return remove(0);
}
/**
* 删除链表中的最后一个元素,返回删除元素
* @return
*/
public E removeLast(){
return remove(size - 1);
}
2.递归
2.1 概述
本质上,将原来的问题,转换为更小的同一问题,递归就是自己调自己
举例 :数组求和
常规的for循环:
public static void main(String[] args) {
int[] arr = {1, 2, 3};
int sum = 0;
for (int i : arr) {
sum += i;
}
System.out.println(sum);
}
使用递归实现:
public static int sum(int[] arr){
return sum(arr,0);
}
private static int sum(int[] arr, int l) {
if (l == arr.length) {
return 0;
}
return arr[l] + sum(arr, l + 1);
}
public static void main(String[] args) {
int[] arr = {1,2,3};
System.out.println(sum(arr));//6
}
2.2 递归实现链表中所有元素
// 递归实现删除链表中的所有元素元素
public ListNode removeElements(ListNode head, int val) {
if (head == null) {
return null;
}
head.next = removeElements(head.next, val);
return head.val == val ? head.next : head;
}