单链表实现队列,栈
首先定义一个单链表Node
static class Node<V> {
Node next;
V value;
public Node(V value) {
this.value = value;
}
}
单链表实现队列,遵循先进先出,后进后出
简单画图说一下解法思路,这里拿inPutTail方法为例(我觉得链表问题画画图就好理解好多了)
第一次插入的时候,因为是从尾巴插入的,所以判断尾巴为空的话就将head和tail指向当前值node(图中的圆圈就是当前值node)
第二次插入的时候,尾巴不为空,所以将尾巴的下一个节点指向当前值node,尾巴指向当前值
也就是
以此类推
static class MyQueue<V> {
Node<V> head;
Node<V> tail;
int size ;
public MyQueue() {
head = null;
tail = null;
size = 0;
}
public void inPutTail(V value) {
Node node = new Node(value);
if (tail == null) {
head = node;
tail = node;
} else {
tail.next = node;
tail = node;
}
size++;
}
public V outPutHead() {
if (head==null){
return null;
}
V value = head.value;
head = head.next;
size--;
if (head==null){
tail =null;
}
return value;
}
public V peekHead() {
if (head==null){
return null;
}
V value = head.value;
return value;
}
public Integer getSize() {
return size;
}
public boolean isEmpty() {
return size == 0;
}
}
单链表实现栈,遵循先进后出,后进先出
inPutHead方法为例
第一次插入的时候,因为是从头插入的,所以判断头为空的话就将head指向当前值node
第二次插入的时候,头不为空,当前值的下一个节点指向老头,老头指向当前值成为新头
也就是
以此类推
static class Mystack<V>{
Node<V> head ;
int size;
public Mystack() {
head = null;
size = 0 ;
}
public void inPutHead(V value){
Node<V> node = new Node<>(value);
if (head==null){
head = node;
}else {
node.next = head;
head = node;
}
size++;
}
public V outPutHead(){
if (head==null){
return null;
}
V value = head.value;
head = head.next;
size--;
return value;
}
public V peekHead(){
return head == null?null:head.value;
}
public Integer getSize() {
return size;
}
public boolean isEmpty() {
return size == 0;
}
}
写个对数器来检验写的队列和栈是否正确,其实就是利用queue队列和随机数检验
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("错了1!");
}
if (myQueue.getSize() != test.size()) {
System.out.println("错了2!");
}
double decide = Math.random();
if (decide < 0.33) {
int num = (int) (Math.random() * maxValue);
myQueue.inPutTail(num);
test.offer(num);
} else if (decide < 0.66) {
if (!myQueue.isEmpty()) {
int num1 = myQueue.outPutHead();
int num2 = test.poll();
if (num1 != num2) {
System.out.println("错了3!");
}
}
} else {
if (!myQueue.isEmpty()) {
int num1 = myQueue.peekHead();
int num2 = test.peek();
if (num1 != num2) {
System.out.println("错了4!");
}
}
}
}
if (myQueue.getSize() != test.size()) {
System.out.println("错了5!");
}
while (!myQueue.isEmpty()) {
int num1 = myQueue.outPutHead();
int num2 = test.poll();
if (num1 != num2) {
System.out.println("错了6!");
}
}
System.out.println("结束!");
}
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("错了1!");
}
if (myStack.getSize()!= test.size()) {
System.out.println("错了2!");
}
double decide = Math.random();
if (decide < 0.33) {
int num = (int) (Math.random() * maxValue);
myStack.inPutHead(num);
test.push(num);
} else if (decide < 0.66) {
if (!myStack.isEmpty()) {
int num1 = myStack.outPutHead();
int num2 = test.pop();
if (num1 != num2) {
System.out.println("错了3!");
}
}
} else {
if (!myStack.isEmpty()) {
int num1 = myStack.peekHead();
int num2 = test.peek();
if (num1 != num2) {
System.out.println("错了4!");
}
}
}
}
if (myStack.getSize() != test.size()) {
System.out.println("错了5!");
}
while (!myStack.isEmpty()) {
int num1 = myStack.outPutHead();
int num2 = test.pop();
if (num1 != num2) {
System.out.println("错了6!");
}
}
System.out.println("结束!");
}
双链表实现双端队列
首先定义一个双链表
static class Node<V> {
Node next;
Node last;
V value;
public Node(V value) {
this.value = value;
}
}
双链表实现双端队列,实现弹出头,弹出尾,插入头,插入尾等
这里拿inPutHead画图简单解释一下
第一次插入头,头尾都指向当前值node
第二次插入头,老头的上一节点指向当前值,当前值的下一节点指向老头,老头指向当前值成为新头
即
以此类推
static class MyDequeue<V> {
Node<V> head;
Node<V> tail;
int size;
public MyDequeue() {
head = null;
tail = null;
size = 0;
}
public void inPutHead(V value) {
Node<V> node = new Node<>(value);
if (head == null) {
head = node;
tail = node;
} else {
head.last = node;
node.next = head;
head = node;
}
size++;
}
public void inPutTail(V value) {
Node<V> node = new Node<>(value);
if (tail == null) {
tail = node;
head = node;
} else {
tail.next = node;
node.last = tail;
tail = node;
}
size++;
}
public V outPutHead() {
if (head == null) {
return null;
}
V ans = head.value;
if (head.next != null) {
head = head.next;
head.last = null;
} else {
head = tail = null;
}
size--;
return ans;
}
public V outPutTail() {
if (tail == null) {
return null;
}
V ans = tail.value;
if (tail.last != null) {
tail = tail.last;
tail.next = null;
} else {
head = tail = null;
}
size--;
return ans;
}
public V peekHead() {
V ans = null;
if (head != null) {
ans = head.value;
}
return ans;
}
public V peekTail() {
V ans = null;
if (tail != null) {
ans = tail.value;
}
return ans;
}
public Integer getSize() {
return size;
}
public boolean isEmpty() {
return size == 0;
}
}
对数器检验是否正确,其实就是利用deque双端队列和随机数检验
public static void testDeque() {
MyDequeue<Integer> myDeque = new MyDequeue<>();
Deque<Integer> test = new LinkedList<>();
int testTime = 5000000;
int maxValue = 200000000;
System.out.println("开始!");
for (int i = 0; i < testTime; i++) {
if (myDeque.isEmpty() != test.isEmpty()) {
System.out.println("错了1!");
}
if (myDeque.getSize() != test.size()) {
System.out.println("错了2!");
}
double decide = Math.random();
if (decide < 0.33) {
int num = (int) (Math.random() * maxValue);
if (Math.random() < 0.5) {
myDeque.inPutHead(num);
test.addFirst(num);
} else {
myDeque.inPutTail(num);
test.addLast(num);
}
} else if (decide < 0.66) {
if (!myDeque.isEmpty()) {
int num1 = 0;
int num2 = 0;
if (Math.random() < 0.5) {
num1 = myDeque.outPutHead();
num2 = test.pollFirst();
} else {
num1 = myDeque.outPutTail();
num2 = test.pollLast();
}
if (num1 != num2) {
System.out.println("错了3!");
}
}
} else {
if (!myDeque.isEmpty()) {
int num1 = 0;
int num2 = 0;
if (Math.random() < 0.5) {
num1 = myDeque.peekHead();
num2 = test.peekFirst();
} else {
num1 = myDeque.peekTail();
num2 = test.peekLast();
}
if (num1 != num2) {
System.out.println("错了4!");
}
}
}
}
if (myDeque.getSize() != test.size()) {
System.out.println("错了5!");
}
while (!myDeque.isEmpty()) {
int num1 = myDeque.outPutHead();
int num2 = test.pollFirst();
if (num1 != num2) {
System.out.println("错了6!");
}
}
System.out.println("结束!");
}