Easily deal with linked list questions during the interview

Source: Internet
Author: User

Copyright. For more information, see the source. Thank you!
Http://blog.csdn.net/walkinginthewind/article/details/7393134

The linked list is the most basic data structure. Interviewers often use the linked list to evaluate the basic abilities of the interviewee. In addition, the linked list-related operations are relatively simple and suitable for investigating the ability to write code. Linked List operations cannot be separated from pointers, which can easily lead to errors. Considering multiple reasons, linked list questions play an important role in the interview. This article comprehensively sorts out the questions related to the linked list, hoping to help students looking for help.

The linked list node declaration is as follows:

Struct listnode
{
Int m_nkey;
Listnode * m_pnext;

};

Question list:

1. Calculate the number of nodes in a single-chain table.
2. Reverse a single-chain table
3. Find the last K node in a single-chain table (k> 0)
4. Find the intermediate node of a single-chain table
5. Print a single-chain table from the end to the end
6. Two single-chain table phead1 and phead2 are known to be in order, and they are merged into a linked list.
7. check whether a single-chain table has loops.
8. Determine whether two single-chain tables are intersecting
9. Find the first node of the intersection of two single-chain tables
10. If a single-chain table is known to have a ring, find the first node in the ring.
11. Given a single-chain header pointer phead and a node pointer ptobedeleted, O (1) time complexity delete node ptobedeleted


Answers

1. Calculate the number of nodes in a single-chain table.

This is the most basic. You should be able to quickly write the correct code and check whether the linked list is empty. The time complexity is O (n ). The reference code is as follows:

// Calculate the number of nodes in a single-chain table. Unsigned int getlistlength (listnode * phead) {If (phead = NULL) return 0; unsigned int nlength = 0; listnode * pcurrent = phead; while (pcurrent! = NULL) {nlength ++; pcurrent = pcurrent-> m_pnext;} return nlength ;}


2. Reverse a single-chain table

Traverse the original linked list from start to end, traverse each node, and remove it to the front end of the new linked list. Note that the linked list is empty and has only one node. The time complexity is O (n ). The reference code is as follows:

// Reverse the listnode * reverselist (listnode * phead) {// If the linked list is empty or has only one node, do not reverse it, directly return the source linked list header pointer if (phead = NULL | phead-> m_pnext = NULL) return phead; listnode * preversedhead = NULL; // The New linked list header pointer after inversion. The initial value is nulllistnode * pcurrent = phead; while (pcurrent! = NULL) {listnode * ptemp = pcurrent; pcurrent = pcurrent-> m_pnext; ptemp-> m_pnext = preversedhead; // remove the current node, insert the front-end preversedhead = ptemp;} return preversedhead;} of the new linked list ;}

3. Find the last K node in a single-chain table (k> 0)

The most common method is to count the number of nodes in a single-chain table, and then find the (n-k) node. Note that the linked list is empty, K is 0, K is 1, and K is greater than the number of nodes in the linked list. The time complexity is O (n ). Code omitted.

Here we will talk about another idea, which will also be applied in other topics.

The main idea is to use two pointers, first let the pointer to the forward K node, so the Distance Difference between the two pointers is K-1, after the two pointers forward together, when the pointer goes to the last knot, the Pointer Points to the nearest node.

The reference code is as follows:

// Query the listnode * rgetkthnode (listnode * phead, unsigned int K) // The R before the function name indicates the reverse {If (k = 0 | phead = NULL) // here, the K count starts from 1, if K is 0 or the linked list is empty, return nullreturn NULL; listnode * pahead = phead; listnode * pbehind = phead; while (k> 1 & pahead! = NULL) // the pointer first goes to the forward K node {pahead = pahead-> m_pnext; k --;} If (k> 1 | pahead = NULL) // if the number of nodes is smaller than K, return nullreturn NULL; while (pahead-> m_pnext! = NULL) // The two pointers move forward together until the Pointer Points to the last node {pbehind = pbehind-> m_pnext; pahead = pahead-> m_pnext;} return pbehind; // The pointer behind the pointer refers to the last K node}

4. Find the intermediate node of a single-chain table

This question can be applied to similar ideas in the previous question. Two pointers are also set, but here is, the two pointers are moving forward at the same time. The previous pointer takes two steps at a time, the next pointer takes one step at a time, and the previous pointer goes to the last knot point, the Pointer Points to the intermediate node, that is, the Nth (n/2 + 1) node. Note that the linked list is empty and the number of linked list nodes is 1 and 2. Time complexity O (n ). The reference code is as follows:

// Obtain the intermediate node of a single-chain table. If the chain table length is n (n> 0), the listnode * getmiddlenode (listnode * phead) of the n/2 + 1 node is returned) {If (phead = NULL | phead-> m_pnext = NULL) // If the linked list is null or has only one node, return the header pointer return phead; listnode * pahead = phead; listnode * pbehind = phead; while (pahead-> m_pnext! = NULL) // The front pointer goes two steps each time until it points to the last node, and the next pointer goes one step each time {pahead = pahead-> m_pnext; pbehind = pbehind-> m_pnext; if (pahead-> m_pnext! = NULL) pahead = pahead-> m_pnext;} return pbehind; // the pointer to the end is the intermediate node}

5. Print a single-chain table from the end to the end

For this sort of reverse order problem, we should think of the stack, and then go first. Therefore, you can either use the stack on your own or let the system use the stack, that is, recursion. Note that the linked list is empty. The time complexity is O (n ). The reference code is as follows:

STACK:

// Print the linked list from the end to the end, and use the stack void rprintlist (listnode * phead) {STD: Stack <listnode *> S; listnode * pnode = phead; while (pnode! = NULL) {S. Push (pnode); pnode = pnode-> m_pnext;} while (! S. Empty () {pnode = S. Top (); printf ("% d \ t", pnode-> m_nkey); S. Pop ();}}

Use recursive functions:

// Print the linked list from the end to the end, and use recursive void rprintlist (listnode * phead) {If (phead = NULL) {return;} else {rprintlist (phead-> m_pnext ); printf ("% d \ t", phead-> m_nkey );}}

6.It is known that two single-chain table phead1 and phead2 are ordered, and they are merged into a linked list.

This is similar to merge sorting. In particular, when both linked lists are empty and one of them is empty. Only the space of O (1) is required. The time complexity is O (max (len1, len2 )). The reference code is as follows:

// Merge two ordered linked lists listnode * mergesortedlist (listnode * phead1, listnode * phead2) {If (phead1 = NULL) return phead2; If (phead2 = NULL) return phead1; listnode * Signature = NULL; If (phead1-> m_nkey <phead2-> m_nkey) {pheadmerged = phead1; signature-> m_pnext = NULL; phead1 = phead1-> m_pnext ;} else {pheadmerged = phead2; pheadmerged-> m_pnext = NULL; phead2 = phead2-> m_pnext;} listnode * ptemp = pheadmerged; while (PHE AD1! = NULL & phead2! = NULL) {If (phead1-> m_nkey <phead2-> m_nkey) {ptemp-> m_pnext = phead1; phead1 = phead1-> m_pnext; ptemp = ptemp-> m_pnext; ptemp-> m_pnext = NULL;} else {ptemp-> m_pnext = phead2; phead2 = phead2-> m_pnext; ptemp = ptemp-> m_pnext; ptemp-> m_pnext = NULL ;}} if (phead1! = NULL) ptemp-> m_pnext = phead1; else if (phead2! = NULL) ptemp-> m_pnext = phead2; return pheadmerged ;}

There are also the following recursive solutions:

ListNode * MergeSortedList(ListNode * pHead1, ListNode * pHead2){if(pHead1 == NULL)return pHead2;if(pHead2 == NULL)return pHead1;ListNode * pHeadMerged = NULL;if(pHead1->m_nKey < pHead2->m_nKey){pHeadMerged = pHead1;pHeadMerged->m_pNext = MergeSortedList(pHead1->m_pNext, pHead2);}else{pHeadMerged = pHead2;pHeadMerged->m_pNext = MergeSortedList(pHead1, pHead2->m_pNext);}return pHeadMerged;}

7. check whether a single-chain table has loops.

Two pointers are also used here. If a linked list has a ring, that is, a pointer is used to traverse it, it will never go through the header. Therefore, we can use two pointers to traverse. one pointer takes two steps at a time, and the other pointer takes one step at a time. If there is a ring, the two pointers will definitely meet in the ring. The time complexity is O (n ). The reference code is as follows:

Bool hascircle (listnode * phead) {listnode * pfast = phead; // The Fast pointer moves forward two steps each time listnode * pslow = phead; // The Slow pointer moves one step forward each time while (pfast! = NULL & pfast-> m_pnext! = NULL) {pfast = pfast-> m_pnext; pslow = pslow-> m_pnext; If (pslow = pfast) // encounter, loop return true ;} return false ;}

8. Determine whether two single-chain tables are intersecting

If the two linked lists intersect with one node, all nodes after the intersection node are shared by the two linked lists. That is to say, if the two linked lists intersect, the last node must be the same. Traverse the first linked list first, remember the last node, and then traverse the second linked list to compare the last node with the last node of the first linked list, otherwise, they do not overlap. The time complexity is O (len1 + len2), because only one Extra pointer is required to save the last node address, and the space complexity is O (1 ). The reference code is as follows:

bool IsIntersected(ListNode * pHead1, ListNode * pHead2){        if(pHead1 == NULL || pHead2 == NULL)                return false;ListNode * pTail1 = pHead1;while(pTail1->m_pNext != NULL)pTail1 = pTail1->m_pNext;ListNode * pTail2 = pHead2;while(pTail2->m_pNext != NULL)pTail2 = pTail2->m_pNext;return pTail1 == pTail2;}

9. Find the first node of the intersection of two single-chain tables
Traverse the first linked list, calculate the length of len1, and save the address of the last node.
Traverse the second linked list, calculate the length of len2, and check whether the last node is the same as the last node of the first linked list. If they are not the same, they do not intersect and end.
The two linked lists start from the first node, assuming that len1 is greater than len2, then the first linked list first traverses the len1-len2 nodes, then the distance between the two linked list current nodes to the first intersection node is equal, then traverse the nodes backward to know that the addresses of the two nodes are the same.

Time Complexity: O (len1 + len2 ). The reference code is as follows:

Listnode * getfirstcommonnode (listnode * phead1, listnode * phead2) {If (phead1 = NULL | phead2 = NULL) return NULL; int len1 = 1; listnode * ptail1 = phead1; while (ptail1-> m_pnext! = NULL) {ptail1 = ptail1-> m_pnext; len1 ++;} int len2 = 1; listnode * ptail2 = phead2; while (ptail2-> m_pnext! = NULL) {ptail2 = ptail2-> m_pnext; len2 ++;} If (ptail1! = Ptail2) // returns nullreturn null directly without intersection; listnode * pnode1 = phead1; listnode * pnode2 = phead2; // first alignment the current node of the two linked lists, make the distance to the End Node equal if (len1> len2) {int K = len1-len2; while (k --) pnode1 = pnode1-> m_pnext ;} else {int K = len2-len1; while (k --) pnode2 = pnode2-> m_pnext;} while (pnode1! = Pnode2) {pnode1 = pnode1-> m_pnext; pnode2 = pnode2-> m_pnext;} return pnode1 ;}

10. If a single-chain table is known to have a ring, find the first node in the ring.

First, determine whether a ring exists. Disconnects a node in the ring (of course, the original linked list cannot be damaged when the function ends). In this way, two overlapping Single-Chain tables are formed, the first node in the ring is converted to the first node for the intersection of two single-chain tables. The reference code is as follows:

Listnode * getfirstnodeincircle (listnode * phead) {If (phead = NULL | phead-> m_pnext = NULL) return NULL; listnode * pfast = phead; listnode * pslow = phead; while (pfast! = NULL & pfast-> m_pnext! = NULL) {pslow = pslow-> m_pnext; pfast = pfast-> m_pnext; If (pslow = pfast) break ;} if (pfast = NULL | pfast-> m_pnext = NULL) return NULL; // use this node in the ring as the end node of the hypothesis, turn it into the intersection problem of two single-chain tables listnode * passumedtail = pslow; listnode * phead1 = phead; listnode * phead2 = passumedtail-> m_pnext; listnode * pnode1, * pnode2; int len1 = 1; listnode * pnode1 = phead1; while (pnode1! = Passumedtail) {pnode1 = pnode1-> m_pnext; len1 ++;} int len2 = 1; listnode * pnode2 = phead2; while (pnode2! = Passumedtail) {pnode2 = pnode2-> m_pnext; len2 ++;} pnode1 = phead1; pnode2 = phead2; // first alignment the current node of the two linked lists, make the distance to the End Node equal if (len1> len2) {int K = len1-len2; while (k --) pnode1 = pnode1-> m_pnext ;} else {int K = len2-len1; while (k --) pnode2 = pnode2-> m_pnext;} while (pnode1! = Pnode2) {pnode1 = pnode1-> m_pnext; pnode2 = pnode2-> m_pnext;} return pnode1 ;}

11. Given a single-chain header pointer phead and a node pointer ptobedeleted, O (1) time complexity delete node ptobedeleted

 

The general idea of deleting a node is to direct the previous node of the node to the next node of the node. In this case, you need to traverse and locate the previous node of the node, the time complexity is O (n ). For the linked list, each node in the linked list has the same structure, so we can copy the data of the next node of the node to the node and then delete the next node. Pay attention to the last node. In this case, you can only use common methods to perform operations. First, find the previous node, but the average time complexity is O (1 ). The reference code is as follows:

Void Delete (listnode * phead, listnode * ptobedeleted) {If (ptobedeleted = NULL) return; If (ptobedeleted-> m_pnext! = NULL) {ptobedeleted-> m_nkey = ptobedeleted-> m_pnext-> m_nkey; // copy data from the next node to the current node, then delete the next node listnode * temp = ptobedeleted-> m_pnext; ptobedeleted-> m_pnext = ptobedeleted-> m_pnext; Delete temp ;} else // The Last node to be deleted {If (phead = ptobedeleted) // The list contains only one node {phead = NULL; Delete ptobedeleted ;} else {listnode * pnode = phead; while (pnode-> m_pnext! = Ptobedeleted) // find the penultimate node pnode = pnode-> m_pnext; pnode-> m_pnext = NULL; Delete ptobedeleted ;}}}

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.