赞
踩
单链表:值、next指针(指向下一个节点)
双链表:值、next指针(指向下一个节点)、last指针(指向上一个节点)
/**
* 单节点:值、next指针
*/
public static class Node{
public int value;
public Node next;
public Node(int data){
this.value = data;
}
}
/**
* 双节点:值、last指针、next指针
*/
public static class DoubleNode{
public int value;
public DoubleNode last;
public DoubleNode next;
public DoubleNode(int data){
this.value = data;
}
}
/** * 反转单链表 * head * | * 1 -> 2 -> 3 -> null * * null <- 1 <- 2 <- 3 * head * @param head * @return */ public static Node reverseLinkedList(Node head){ Node pre = null; Node next = null; /** * 反转单链表: 1 -> 2 -> 3 -> null * head为1时: * 1 的 next指针为 2 * 反转时,先将next指针保留为next * 然后将 1 的next指针指向 null * 将当前head(1) 记录为 pre(上一个) * 将next (2) 记录为 head * ------------------- * head为2时: pre 为 1 * 将head(2)的next指针保留为next * 将head(2)的next指针指向pre * 将head(2)记录为pre * 将head(2)记录为next(3) * ------------------- * head为3时:pre为2 同上,但是head(3)记录为next(null) * ------------------- * head 为 null 结束循环,同时返回pre:此时head为3 * */ while (head != null){ next = head.next; head.next = pre; pre = head; head = next; } return pre; }
/** * 反转双链表 * head * null <- 1 <-> 2 <-> 3 -> null * * null <- 1 <-> 2 <-> 3 -> null * head * @param head * @return */ public static DoubleNode reverseDoubleLinkedList(DoubleNode head){ DoubleNode pre = null; DoubleNode next = null; while (head != null){ /** * 首先head为 1 时: pre 为null * 此时记录head(1)的next(2)指针 * 把 head(1)的next指针指向pre(null) * 把 head(1)的last指针指向next(2) * 将 pre 记录为 head(1) * 将 head 记录为 next(2) * ---------------------------------- * 当head为2时:pre为1 * 记录head(2)的 next(3)指针, * 将head(2)的next指向pre(1) * 将head(2)的last指针指向next(3) * 再将 pre(此时为1) 记录为 head 2 * 将 head(此时为2) 记录为 next(3) * ---------------------------------- * 当head为3时:pre为2 * 记录 head(3)的next指针(null) * 将 head(3)的next指针指向pre (2) * 将 head(3)的last指针指向next (null) * 把 pre(此时为2)记录为 head(3) * 把 head(此时为3)记录为 next(null) * ---------------------------------- * 当head为null, 结束循环。 * */ next = head.next; head.next = pre; head.last = next; pre = head; head = next; } return pre; }
public static void main(String[] args) { Node n1 = new Node(1); n1.next = new Node(2); n1.next.next = new Node(3); // 123 -> 321 n1 = reverseLinkedList(n1); while (n1 != null){ System.out.print(n1.value+" "); n1 = n1.next; } System.out.println(); System.out.println("============"); DoubleNode d1 = new DoubleNode(1); d1.next = new DoubleNode(2); d1.next.next = new DoubleNode(3); d1.next.last = d1; d1 = reverseDoubleLinkedList(d1); while (d1 != null){ System.out.print(d1.value+" "); d1 = d1.next; } }
队列的特点:先进先出,正常的排队顺序。
public static class Node<V>{
public V value;
public Node<V> next;
public Node(V v){
this.value = v;
this.next = null;
}
}
public static class MyQueue<V>{ //三个属性 //头 private Node<V> head; //尾 private Node<V> tail; //大小 private int size; //无参构造 public MyQueue(){ this.head = null; this.tail = null; this.size = 0; } public boolean isEmpty(){ return size == 0; } public int size(){ return size; } /** * 入队 * @param value */ public void offer(V value){ Node<V> cur = new Node<>(value); if (tail == null){ head = cur; tail = cur; }else { tail.next = cur; tail = cur; } size++; } /** * 弹出元素 * @return */ public V poll(){ V ans = null; if (head != null){ ans = head.value; head = head.next; size--; } if (head == null){ tail = null; } return ans; } /** * 查看队列尾部的元素 * @return */ public V peek(){ V ans = null; if (head != null){ ans = head.value; } return ans; } }
/** * 队列 对数器 */ public static void testQueue() { MyQueue<Integer> myQueue = new MyQueue<>(); Queue<Integer> test = new LinkedList<>(); int testTime = 5000000; int maxValue = 200000000; System.out.println("测试开始!"); for (int i = 0; i < testTime; i++) { if (myQueue.isEmpty() != test.isEmpty()) { System.out.println("Oops!"); } if (myQueue.size() != test.size()) { System.out.println("Oops!"); } double decide = Math.random(); if (decide < 0.33) { int num = (int) (Math.random() * maxValue); myQueue.offer(num); test.offer(num); } else if (decide < 0.66) { if (!myQueue.isEmpty()) { int num1 = myQueue.poll(); int num2 = test.poll(); if (num1 != num2) { System.out.println("Oops!"); } } } else { if (!myQueue.isEmpty()) { int num1 = myQueue.peek(); int num2 = test.peek(); if (num1 != num2) { System.out.println("Oops!"); } } } } if (myQueue.size() != test.size()) { System.out.println("Oops!"); } while (!myQueue.isEmpty()) { int num1 = myQueue.poll(); int num2 = test.poll(); if (num1 != num2) { System.out.println("Oops!"); } } System.out.println("测试结束!"); } public static void main(String[] args) { testQueue(); }
栈的特点:先进后出,可以理解为弹夹,最先压入的子弹最后打出去。
/** * 2. 单链表实现栈结构 * @param <V> */ public static class MyStack<V>{ private Node<V> head; private int size; public MyStack(){ this.head = null; this.size = 0; } public boolean isEmpty(){ return size == 0; } public int size(){ return size; } /** * 入栈 * @param value */ public void push(V value){ Node cur = new Node(value); if (head == null){ //如果栈为空, 则head = cur head = cur; }else { //如果栈不为空,则cur的next指向当前head,并且head记录为cur cur.next = head; head = cur; } size++; } /** * 弹出栈元素 * @return */ public V pop(){ V ans = null; if (head != null){ //如果栈不为空,则直接返回head的value,并且head记录为head的next指针。 ans = head.value; head = head.next; size--; } return ans; } public V peek(){ return head.value == null ? null:head.value; } }
/** * 栈 对数器 */ public static void testStack() { MyStack<Integer> myStack = new MyStack<>(); Stack<Integer> test = new Stack<>(); int testTime = 5000000; int maxValue = 200000000; System.out.println("测试开始!"); for (int i = 0; i < testTime; i++) { if (myStack.isEmpty() != test.isEmpty()) { System.out.println("Oops!"); } if (myStack.size() != test.size()) { System.out.println("Oops!"); } double decide = Math.random(); if (decide < 0.33) { int num = (int) (Math.random() * maxValue); myStack.push(num); test.push(num); } else if (decide < 0.66) { if (!myStack.isEmpty()) { int num1 = myStack.pop(); int num2 = test.pop(); if (num1 != num2) { System.out.println("Oops!"); } } } else { if (!myStack.isEmpty()) { int num1 = myStack.peek(); int num2 = test.peek(); if (num1 != num2) { System.out.println("Oops!"); } } } } if (myStack.size() != test.size()) { System.out.println("Oops!"); } while (!myStack.isEmpty()) { int num1 = myStack.pop(); int num2 = test.pop(); if (num1 != num2) { System.out.println("Oops!"); } } System.out.println("测试结束!"); }
public static void main(String[] args) {
testStack();
}
双端队列:即从队列头部和尾部都可以入队元素和出队元素。
public static class MyDoubleQueue<V>{ private Node<V> head; private Node<V> tail; private int size; public MyDoubleQueue(){ head = null; tail = null; size = 0; } public boolean isEmpty(){ return size == 0; } public int size(){ return size; } /** * 从头部加元素 * @param v */ public void lpush(V v){ Node<V> cur = new Node<>(v); //队列为空 if (head == null){ head = cur; tail = cur; }else { //队列不为空 head // null 1 2 3 null //null 4(cur) 1 2 3 null // head cur.next = head; head.last = cur; head = cur; } size ++; } /** * 从头部弹出元素 * @return */ public V lpop(){ V ans = null; //队列为空 if(head == null){ return ans; } //队列不为空,弹出一个元素,队列大小-1 size -- ; ans = head.value; //队列只有一个元素,弹出元素后,head和tail 置空 if (head == tail){ head = null; tail = null; }else { //队列中存在两个及以上元素,弹出头部元素后,head移动到next指针,并将此时的head的last置为null。 head = head.next; head.last = null; } return ans; } /** * 从尾部加入元素 * @param v */ public void rpush(V v){ Node<V> cur = new Node<>(v); if (tail == null){ //如果队列为空 head = cur; tail = cur; }else { //队列不为空 tail // null 1 2 3 null // null 1 2 3 4 null // tail cur.last = tail; tail.next = cur; tail = cur; } size ++; } public V rpop(){ V ans = null; if (tail == null){ return ans; } size --; ans = tail.value; if (head == tail){ head = null; tail = null; }else { tail = tail.last; tail.next = null; } return ans; } public V lpeek(){ return head == null ? null : head.value; } public V rpeek(){ return tail == null ? null : tail.value; } }
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。