I. Question
Given the head pointer and a node pointer of the linked list, delete the node at O (1) time. The linked list node is defined as follows:
Struct listnode
{
Int m_nkey;
Listnode * m_pnext;
};
The function declaration is as follows:
Void deletenode (listnode * plisthead, listnode * ptobedeleted );
Ii. Analysis
This is a widely spread Google interview question. It can effectively evaluate our basic programming skills, our response speed, and more importantly, our understanding of time complexity.
Delete a node from the linked list. The most common practice is to start from the head node of the linked list, search for the node to be deleted in sequence, and delete it again. Because sequential search is required, the time complexity is O (n.
The reason why we need to start from the node to find the node to be deleted is that weYou need to obtain the first node of the node to be deleted..
"Fake cat": You can get the next node of a given node to be deleted. In this case, we actually Delete the next node. before deleting the node, we needData of the next nodeCopy to a given node and delete the next node of the node. At this time, the time complexity is O (1 ).
The above thinking has another question: What if the deleted node is located at the end of the linked list and there is no next node? We still start from the head node of the linked list, traverse the forward node of the given node by the way, and complete the deletion operation. In this case, the time complexity is O (n ).
The question requires that we need to complete the deletion operation at O (1) time. Is our algorithm not compliant? In fact, assume that the linked list has n nodes in total. In the case of N-1, the time complexity of our algorithm is O (1). Only when the given node is at the end of the linked list, the time complexity is O (n ). Then the average time complexity [(n-1) * O (1) + O (n)]/n is still O (1 ).
3. Source Code
# Include <iostream> using namespace STD; struct node {int data; node * Next;}; node * creat () {node * head = new node (); head-> DATA = 0; head-> next = NULL; For (INT I = 10; I> 0; -- I) {node * temp = new node (); temp-> DATA = I; temp-> next = NULL; temp-> next = head-> next; head-> next = temp;} return head ;} node * findlastnode (node * head, int data) {While (Head! = NULL & head-> data! = Data) {head = head-> next;} return head;} void deletenode (node * head, node * del) {If (Del-> next! = NULL) {del-> DATA = del-> next-> data; del-> next = del-> next ;} else {/* This is the method for deleting the last node */node * pre = findlastnode (Head, 9); pre-> next = pre-> next ;}} void print (node * head) {While (Head! = NULL) {cout
It is worth noting that in order to make the Code look concise, the above Code is based on two assumptions:
(1) The given node is indeed in the linked list;
The first assumption does not affect the robustness of the Code.
(2) The given node to be deleted is not the head node of the linked list.
As for the second assumption, the Code may be faulty when there is only one knot in the entire list. But this assumption is not too much, because in some linked list implementations, a virtual linked list header is created, and it is not an actual linked list node. In this way, the node to be deleted cannot be the head node of the linked list.