package com.company;
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);
}
@Override
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;
}
//在链表头添加元素
public void addFirst(E e){
add(e,0);
}
//在链表中间index位置添加元素
public void add(E e, int index){
if(index <0 || index > size)
throw new IllegalArgumentException("added failed");
else{
Node pre = dummyhead;
for(int i=0; i <index; i++ )
pre = pre.next;
//Node node = new Node(e);
//node.next = pre.next;
// pre.next = node;
pre.next = new Node(e, pre.next);
size++;
}
}
public void addLast(E e){
add(e, size);
}
//获得链表第index位置的元素
public E get(int index){
if(index <0 || index > size)
throw new IllegalArgumentException("get failed");
Node cur = dummyhead.next;
for(int i= 0; i<index; i++){
cur = cur.next;
}
return cur.e;
}
//获得链表第一个元素
public E getFirst(){
return get(0);
}
public E getLast(){
return get(size-1);
}
//修改链表第index位置的元素
public void set(int index, E e){
if(index <0 || index > size)
throw new IllegalArgumentException("set failed");
Node cur = dummyhead.next;
for(int i= 0; i<index; i++){
cur = cur.next;
}
cur.e = e;
}
//查找是否存在元素e
public boolean contain(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();
}
//删除index位置的元素
public E remove(int index){
if(index <0 || index > size)
throw new IllegalArgumentException("remove failed");
Node pre = dummyhead;
for(int i= 0; i<index; i++){
pre = pre.next;
}
Node retnode = pre.next;
pre.next = retnode.next;
retnode = null;
size--;
return retnode.e;
}
public E removeFirst(){
return remove(0);
}
public E removelast(){
return remove(size);
}
}
二 时间复杂度分析
三 链表实现栈
package com.company;
public class LinkedListStack<E> implements Stack<E> {
LinkedList<E> list;
public LinkedListStack(){
list = new LinkedList<>();
}
@Override
public int getSize(){
return list.getSize();
}
@Override
public boolean isEmpty(){
return list.isEmpty();
}
@Override
public void push(E e){
list.addFirst(e);
}
@Override
public E pop(){
return list.removeFirst();
}
@Override
public E peek(){
return list.getFirst();
}
@Override
public String toString(){
StringBuilder res = new StringBuilder();
res.append("stack: top ");
res.append(list);
return res.toString();
}
public static void main(String[] args){
LinkedListStack<Integer> stack = new LinkedListStack<>();
for(int i = 0; i< 5; i++){
stack.push(i);
System.out.println(stack);
}
stack.pop();
System.out.println(stack);
}
}
四 链表实现队列
package com.company;
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);
}
@Override
public String toString(){
return e.toString();
}
;
}
private Node head, tail;
private int size;
private 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) { //意味着head也为空
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("can not dequeue from an empty queue");
Node retNode = head;
head = head.next;
retNode.next = null;
if(head == null) // 出队列最后为空了
tail = null;
size--;
return retNode.e;
}
public E getFront(){
if(isEmpty())
throw new IllegalArgumentException("can not getFront from an empty queue");
return head.e;
}
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();
}
}
五 链表和递归
删除链表中的元素
import java.util.List;
public class Solution {
public ListNode removeElements(ListNode head, int val){
while(head != null && head.val == val) { //假若头节点就是要删除的元素(if) 再后的节点也是 那就到第一个不是要删除元素的节点
ListNode delNode =head;
head = head.next;
delNode = null;
}
if(head == null) //删除完变成空了
return null;
ListNode prev =head;
while(prev.next != null){
if(prev.val == val){
ListNode delNode = prev;
prev = prev.next;
delNode = null;
}
else
prev = prev.next;
}
return head;
}
}
使用虚拟头节点
public class Solution {
public ListNode removeElements(ListNode head, int val){
ListNode dummyhead = new ListNode(-1);
dummyhead.next = head; //无需对头节点进行特殊处理
// while(head != null && head.val == val) { //假若头节点就是要删除的元素(if) 再后的节点也是 那就到第一个不是要删除元素的节点
// ListNode delNode =head;
// head = head.next;
// delNode = null;
// }
//if(head == null) //删除完变成空了
// return null;
ListNode prev =dummyhead;
while(prev.next != null){
if(prev.val == val){
ListNode delNode = prev;
prev = prev.next;
delNode = null;
}
else
prev = prev.next;
}
return head;
}
}
六 链表和递归
public class Solution3 {
public ListNode removeElements(ListNode head, int val){
if(head == null)
return null;
ListNode res = removeElements(head.next, val);
if(head.val == val)
return res;
else{
head.next = res;
return head;
}
}
七 递归函数的微观解读
调试样例:
public class Solution3 {
public ListNode removeElements(ListNode head, int val, int depth){ //删除所有重复的节点 所以最后递归到null
//如果是删除某个节点递归结束条件可以改一哈
String depthString = generateDepthString(depth);
System.out.println(depthString);
System.out.println("Call: remove" + val + " in " +head);
if(head == null){
System.out.print(depthString);
System.out.println("Return:" + head);
return null;
}
ListNode res = removeElements(head.next, val, depth+1);
System.out.print(depthString);
System.out.println("After remove:" + val + ":" + res);
ListNode ret;
if(head.val == val)
ret = res;
else{
head.next = res;
ret = head;
}
return ret;
}x
private String generateDepthString(int depth){
StringBuilder res = new StringBuilder();
for(int i=0; i< depth; i++){
res.append("--");
}
return res.toString();
}
public static void main(String[] args){
int[] nums ={1,2,6,3,4,5,6};
ListNode head = new ListNode(nums);
System.out.println(head);
ListNode res = (new Solution3()).removeElements(head,6,0);
System.out.println(res);
}
}
public class ListNode {
public ListNode next;
public int val;
public ListNode(int val){
this.val = val;
}
//链表节点的构造函数
//使用arr为参数 创建一个链表 当前lsitnode为链表头节点
public ListNode(int[] arr){
if(arr == null || arr.length == 0){
throw new IllegalArgumentException("arr can not be empty");
}
this.val = arr[0];
ListNode cur = this;
for(int i=1; i<arr.length; i++){
cur.next = new ListNode(arr[i]);
cur = cur.next;
}
}
@Override
public String toString(){
StringBuilder sb = new StringBuilder();
ListNode cur = this;
while (cur != null){
sb.append(cur.val + "-->");
cur = cur.next;
}
sb.append("null");
return sb.toString();
}
}
八 更多和链表有关的问题