今天我们来聊聊单节点和双向节点的一些知识吧!
我们在刷算法题的时候,由于力扣等网站已经给我们写好了节点类的定义,但是我们还是要明白它是怎么定义的。
例如,在单向节点中是这样的:
public static class Node{
public int value;
public Node next;
public Node(int data){
value = data;
}
}
在双向节点又是这样定义的:
public static class DoubleNode{
public int value;
public DoubleNode next;
public DoubleNode last;
public DoubleNode(int data){
value = data;
}
}
在我们了解节点是如何定义后,让我们来尝试一下如何实现反转链表吧。
在单向链表中,我们可以这样来实现:
public static Node reverseLinkedList(Node head){
Node pre = null;
Node next = null;
while(head!=null){
next= head.next;
head.next=pre;
pre=head;
head= next;
}
return pre;
}
在双向链表中这样实现:
public static DoubleNode reverseDoubleList(DoubleNode head){
DoubleNode pre = null;
DoubleNode next = null;
while (head!=null){
next = head.next;
head.next=pre;
head.last= next;
pre=head;
head=next;
}
return pre;
}
在面试中,我们会经常被问到,如何删除链表中的一个数,让我们来看看是如何实现的吧。
//删除一个数
public static Node removeValue(Node head,int num){
while (head!=null){
if(head.value!=num){
break;
}
head=head.next;
}
Node pre = head;
Node cru = head;
while (cru!=null){
if(cru.value==num){
pre.next=cru.next;
}else {
pre=cru;
}
cru=cru.next;
}
return head;
}
学完了这些,接下来我们来聊聊队列和栈吧!
接下来我们来实现一下队列和栈的实现:
public static class Node<T>{
public T value;
public Node<T> last;
public Node<T> next;
public Node(T data){
value = data;
}
}
public static class DoubleEndsQueue<T>{
public Node<T> head;
public Node<T> tail;
public void addFromHead(T value){
Node<T> cur = new Node<>(value);
if(head==null){
head = cur;
tail = cur;
}
else {
cur.next = head;
head.last = cur;
head = cur;
}
}
public void addFromBottom(T value){
Node<T> cur = new Node<>(value);
if(head==null){
head = cur;
tail = cur;
}
else {
tail.next = cur;
cur.last = tail;
tail=cur;
}
}
public T popFromHead(){
if(head==null){
return null;
}
Node<T> cur = head;
if(head==tail){
head=null;
tail=null;
}
else {
head=head.next;
cur.next=null;
head.last=null;
}
return cur.value;
}
public T popFromBottom(){
if(head==null){
return null;
}
Node<T> cur = tail;
if(head==tail){
head=null;
tail=null;
}
else {
tail=tail.last;
tail.next=null;
cur.last=null;
}
return cur.value;
}
public boolean isEmpty(){
return head==null;
}
}
public static class Mystack<T>{
private DoubleEndsQueue<T> queue;
public Mystack(){
queue = new DoubleEndsQueue<>();
}
public void push(T value){
queue.addFromHead(value);
}
public void pop(){
queue.popFromHead();
}
public boolean isEmpty(){
return queue.isEmpty();
}
}
public static class MyQueue<T>{
private DoubleEndsQueue<T> queue;
public MyQueue(){
queue = new DoubleEndsQueue<>();
}
public void push(T value){
queue.addFromHead(value);
}
public void pop(){
queue.popFromBottom();
}
public boolean isEmpty(){
return queue.isEmpty();
}
}
是不是发现原来也不过如此!
好啦!到最后我们来放松一下,学一学递归的简单用法吧!
public static void main(String[] args) {
int[] arr = {1,3,5,7,9,2,4,6,8};
int max = getMax(arr);
System.out.println(max);
}
public static int getMax(int[] arr){
return process(arr,0,arr.length-1);
}
public static int process(int[] arr,int L,int R){
if(L==R){
return arr[L];
}
int mid = L + ((R-L)>>1);
int leftMax = process(arr,L,mid);
int rightMax = process(arr,mid+1,R);
return Math.max(leftMax,rightMax);
}
好啦!今天就到这里啦!下期再见!