Yesterday's Java implementation of the Singleton mode, our double check lock mechanism because of the order reordering problem introduced the volatile
keyword, many friends asked me, in the end why to add volatile
this keyword Ah, and it, in the end, what magic role?
To volatile
this keyword, in yesterday's explanation we briefly said: The volatile
modified shared variable, will have the following two properties:
- Guarantees the memory visibility of different threads for this variable operation.
- Prohibit command reordering.
Shared variables: If a variable has a copy in the working memory of multiple threads, then this variable is a shared variable for these threads.
Visibility: A thread's modification of shared variable values can be seen by other threads in a timely manner.
For reordering, unfamiliar advice directly to Google, there is not much to mention. Just remember that when working with a shared variable in a multi-threaded operation, it is important to remember to add a volatile
modifier.
Because of the time, we still have to enter the topic of today, for the volatile
keyword, in the requirements of concurrent programming ability of the interview is very easy to examine, I will briefly explain to you later.
Enter the head node of a single linked list and print out the value of each node from the end of the tail.
This is "The sword refers to offer" on the fifth interview problem, linked list is often in the interview of a data structure, so recommend everyone must master. Not familiar with the list of small partners can be sure to go to the "Big talk data Structure" a good lesson yo ~
"Sword Point offer" PDF version in the public number backstage reply "sword refers to offer" can be obtained. "
"Big Talk Data Structure" PDF version in the public number back "big talk data structure" can be obtained.
Our list has many, single-linked lists, doubly linked lists, linked lists and so on. This is the most common single-linked list mode, where we typically store data in the data storage area and then have a pointer pointing to the next node. Although there is no concept of pointers in Java, Java references are appropriate to fill this issue.
Seeing this problem, we tend to react quickly to each node having the next attribute, so it's easy to output from the beginning to the end. So we will naturally think of a while
loop to take out all the nodes into the array, and then through the inverse of this array, you can reverse print a single linked list node value.
We assume that the data for the node is of type int. The implementation code is as follows:
PublicClassTest05 {
PublicStaticClassNode {
int data;
Node Next;
}
PublicStaticvoidPrintlinkreverse(Node head) {
arraylist<node> nodes =New Arraylist<> ();
while (head! =NULL) {
Nodes.Add (head);
head = Head.next;
}
for (int i = nodes.size ()-1; I >=0; i--) {
System.out.print (Nodes.get (i). Data +" ");
}
}
PublicStaticvoidMain(string[] args) {
Node head =New Node ();
Head.data =1;
Head.next =New Node ();
Head.next.data =2;
head.next.next = new node ();
head.next.next.data = 3;
head.next.next.next = new node ();
head.next.next.next.data = 4;
head.next.next.next.next = new node ();
head.next.next.next.next.data = 5;
printlinkreverse (head);
}
}
Such a way can actually achieve reverse print list of data, but obviously used a full two cycles, the time complexity of O (n²). Wait a minute! Reverse output? There seems to be a data structure that solves this problem perfectly, and this data structure is a stack.
Stack is a "LIFO" data structure, with the principle of the stack to better meet our requirements, so the implementation code is as follows:
PublicClassTest05 {
PublicStaticClassNode {
int data;
Node Next;
}
PublicStaticvoidPrintlinkreverse(Node head) {
stack<node> stack =New Stack<> ();
while (head! =NULL) {
Stack.push (head);
head = Head.next;
}
while (!stack.isempty ()) {
System.out.print (Stack.pop (). Data +" ");
}
}
PublicStaticvoidMain(string[] args) {
Node head =New Node ();
Head.data =1;
Head.next =New Node ();
Head.next.data =2;
head.next.next = new node ();
head.next.next.data = 3;
head.next.next.next = new node ();
head.next.next.next.data = 4;
head.next.next.next.next = new node ();
head.next.next.next.next.data = 5;
printlinkreverse (head);
}
}
Since it can be implemented using stacks, it is also very easy to think of recursion as a solution to this problem, because recursion is essentially a stack structure. To implement the reverse output linked list, every time we visit a node, we first recursively output the node behind it, and then output the node itself, so that the output of the linked list is naturally the reverse.
The code is as follows:
PublicClassTest05 {
PublicStaticClassNode {
int data;
Node Next;
}
PublicStaticvoidPrintlinkreverse(Node head) {
if (head! =NULL) {
Printlinkreverse (Head.next);
System.out.print (head.data+" ");
}
}
PublicStaticvoidMain(string[] args) {
Node head =New Node ();
Head.data =1;
Head.next =New Node ();
Head.next.data =2;
head.next.next = new node ();
head.next.next.data = 3;
head.next.next.next = new node ();
head.next.next.next.data = 4;
head.next.next.next.next = new node ();
head.next.next.next.next.data = 5;
printlinkreverse (head);
}
}
Although the recursive code does look neat, there is a problem: When the list is very long, it must cause the function call to be very deep, which may cause the function call stack to overflow. So it's better to show the code with the stack based on the loop implementation.
Well, today's interview explanation is here, we'll see you tomorrow!
Interview: Print a linked list in reverse Java