Question: Enter the head node of a linked list, reverse the linked list, and return the head node of the linked list. The linked list node is defined as follows:
Struct listnode
{
Int m_nkey;
Listnode * m_pnext;
};
Analysis: This is a widely used Microsoft interview question. Since this question can reflect the strict thinking of programmers, many companies have adopted this question during interviews since Microsoft.
To correctly reverse a linked list, you need to adjust the pointer direction. Code related to pointer operations is always error-prone, so it is best to perform a comprehensive analysis before you write a program. During the interview, the interviewer will be very impressed by the careful analysis and design at the beginning, because in actual software development, the design time is always longer than the code writing time. Rather than writing a piece of code that is full of loopholes, it is far better to write a piece of robust code with a lot of time.
In order to clearly analyze the complex process of adjusting pointers, we can use graphs for visual analysis. Assume that l, m, and n are three adjacent nodes:
A branch B branch... Limit l mà nà...
After several operations, we have adjusted the pointer before node L. The m_pnext pointer of these nodes points to the previous node. Now we traverse to the node M. Of course, we need to adjust the m_pnext pointer of the node to point it to node L. Note that the linked list is disconnected once the pointer pointing is adjusted, as shown in:
A branch B branch... L limit M nà...
Because no Pointer Points to node N, we cannot traverse node n any more. Therefore, to avoid the disconnection of the linked list, we need to save n before adjusting M's m_pnext.
Next, we try to find the head node of the reverse linked list. It is not difficult to find that the head node of the inverted linked list is the tail node of the original linked list. What node is the end node? It is the node where m_pnext is a null pointer.
Based on the above analysis, we can easily write the following code:
//////////////////////////////////////// ///////////////////////////////
// Reverse a list iteratively
// Input: phead-the head of the original list
// Output: the head of the reversed head
//////////////////////////////////////// ///////////////////////////////
Listnode * reverseiteratively (listnode * phead)
{
Listnode * preversedhead = NULL;
Listnode * pnode = phead;
Listnode * pprev = NULL;
While (pnode! = NULL)
{
// Get the next node, and save it at pnext
Listnode * pnext = pnode-> m_pnext;
// If the next node is null, The currect is the end of original
// List, and it's the head of the reversed list
If (pnext = NULL)
Preversedhead = pnode;
// Reverse the linkage between nodes
Pnode-> m_pnext = pprev;
// Move forward on the list
Pprev = pnode;
Pnode = pnext;
}
Return preversedhead;
}
Extension: This question can also be implemented recursively. If you are interested, please write your own recursive code.
The reversal of a one-way linked list is a frequently asked interview question, which is also a very basic question. For example, a linked list is like this: 1-> 2-> 3-> 4-> 5, and then 5-> 4-> 3-> 2-> 1. The easiest way to traverse the linked list is to use an auxiliary pointer to store the next element pointed to by the current pointer during the traversal process. After the pointer of the element on the current node is reversed, use the stored pointer to traverse the backend. The source code is as follows:
struct linka { int data; linka* next;};void reverse(linka*& head){ if(head ==NULL) return; linka*pre, *cur, *ne; pre=head; cur=head->next; while(cur) { ne = cur->next; cur->next = pre; pre = cur; cur = ne; } head->next = NULL; head = pre;}
There is also a method that uses recursion. The basic idea of this method is to call recursive functions to reverse the subsequent nodes before reversing the current node. The source code is as follows. However, this method has one disadvantage: The last node after the inversion will form a ring, so the next field of the node returned by the function must be set to null. I used a reference to change the head pointer. The source code of the algorithm is as follows:
linka* reverse(linka* p,linka*& head){ if(p == NULL || p->next == NULL) { head=p; return p; } else { linka* tmp = reverse(p->next,head); tmp->next = p; return p; }}