Pseudo code of linked list
1. A recursive algorithm is designed to delete all the nodes with the value of x in the single linked list L without the leading node
Writing thought; 1)Establish recursive function and judge each round L->data Is it x,If yes, delete the node, and then L = L->next,Until the end of the linked list is traversed L->next = NULL
LNode *getElemByPos(LinkList L,int i) { int j = 1; LNode *P = L->next; if (i == 0) { return L; } if (i < 1) { return NULL; } while (P != NULL && j < i) { P = P->next; j++; } return P; } void delX(LinkList &L,ElemType x) { int i = 1; // No lead node if (L != NULL) { if (L->data == x) { LNode *P = getElemByPos(L,i-1); P->next = L->next; } i++; delX(L,x); } else { return ; } }
Time complexity:
O
(
n
)
O(n)
O(n)
Space complexity:
O
(
n
)
O(n)
O(n)
Reference answer:
Written thought: 1)Termination condition: table empty 2)Divide into smaller problems: assume that the header pointer is L If the header element is X,Delete X,Sub table is L->next,Perform the same operation If the header element is not X,Sub table is L->next,Perform the same operation
void delX(LinkList &L,ElemType x) { // End of empty table if (L == NULL) { return ; } // Delete the node whose data field is equal to X if (L->data == x) { // Node where X is temporarily stored LNode *P = L; // L points to the next node of the node where X is located L = L->next; // Release the node where X is located free(P); // Recursive processing of sub tables delX(L,x); } else { // If the data field of the first node is not x, the sub table L - > next will be processed delX(L->next,x); } }
2. In the single linked list L of the leading node, delete all nodes with the value of x and free up space. Assuming that the node with the value of x is not unique, try to write an algorithm to realize the above operation.
Written thought: The difference from the above question is that it has a head node and does not require recursion, so you can use a loop to replace tail recursion, and the idea remains the same
void delX(LinkList &L,ElemType x) { // Skip over node L = L->next; int i = 1; // As long as the node is not empty, the operation will continue while (L != NULL) { if (L->data == x) { // Store current node LNode *P = L; // Storage precursor node LNode *Q = getElemByPos(L,i-1); // Make the linked list continuous Q->next = P->next; L = L->next; free(P); } i++; } } LNode *getElemByPos(LinkList L,i) { if (i == 0) { return NULL; } if (i < 1) { return ; } int j = 1; while (L != NULL && j < i) { L = L->next; j++; } return L; }
Time complexity:
O
(
n
)
O(n)
O(n)
Space complexity:
O
(
1
)
O(1)
O(1)
Reference answer:
Written thought: 1)Will table L The head node of is disconnected from its subsequent part 2)Traverse the post order part, and its value is not equal to x Execute tail insertion to the node of L After the head node of; For a value equal to x Node to perform the release operation
void delXByTailInsert(LinkList L,ElemType x) { LNode *subHead = L->next; // Removed sub table header LNode *tailL = L; // L indicates the footer of the table LNode *aux; // Working pointer while (subHead != NULL) { // The tail is inserted into the tail of the table represented by L if (subHead->data != x) { // Insert footer and update footer pointer tailL->next = subHead; tailL = subHead; // Child table backward subHead = subHead->next; // Release current node of child table } else { // Temporary storage of current node aux = subHead; // Move sub table header backward subHead = subHead->next; // release free(aux); } } // The next of the tail node of the table represented by L is set to NULL tailL->next = NULL; }
Time complexity: O ( n ) O(n) O(n) space complexity: O ( 1 ) O(1) O(1)
3. Let L be the single linked list of the leading node, and write an algorithm to output the value of each node from end to end
Written thought: 1)To realize the reverse output from beginning to end, you can think of a single linked list"Head insertion" 2)be careful L Is the single linked list of the leading node
bool LinkReverse(LinkList &L) { if (L == NULL) { return false; } // Skip over node LNode *subHead = L->next; L->next = NULL; while (subHead != NULL) { // aux stores the current node LNode *aux = subHead; // Child table node backward subHead = subHead->next; // Insert the current node into L aux->next = L->next; L->next = aux; free(aux); } return true; }
Time complexity: O ( n ) O(n) O(n) space complexity: O ( 1 ) O(1) O(1)
4. Write an efficient algorithm to delete a minimum node in the single linked list L of the leading node (assuming that the minimum node is unique)
Written thought: 1)Traverse the entire single linked list, create a pointer variable, receive the current node and its predecessor nodes, and update the pointer to the current node if it is smaller than its value 2)Throughout the loop, the pointer points to the minimum node
void delMinNode(LinkList &L) { // Storage header node LNode *subHead = L; L = L->next; ElemType min = L->data; // The precursor node that stores the minimum value node LNode *aux; // The loop does not exit until the table is empty while (subHead != NULL) { // If it is smaller than min, update the min value and record the precursor node if (min > subHead->next->data) { min = subHead->next->data; aux = subHead; } // Point to the next node subHead = subHead->next; } // The last aux points to the precursor node of the minimum node LNode *Z = aux->next; aux->next = Z->next; free(Z); }
Time complexity: O ( n ) O(n) O(n) space complexity: O ( 1 ) O(1) O(1)
5. Try to write an algorithm to reverse the single linked list of the leading node in place. The so-called "in place" means that the complexity of the auxiliary space is O ( 1 ) O(1) O(1)
Written thought: 1)It is required to store single linked list data in reverse order, and the header insertion method of single linked list can be considered
void LinkReverse(LinkList &L) { // Node behind storage header node LNode *subHead = L->next; // Exists as a header node L->next = NULL; LNode *aux; while (subHead != NULL) { // Store current node aux = subHead; subHead = subHead->next; L->next = aux; } }
Time complexity: O ( n ) O(n) O(n) space complexity: O ( 1 ) O(1) O(1)
6. There is a single linked list L with leading nodes. Design an algorithm to make its elements increase and order
Written thought: 1)Use array storage L The values of the elements in the, and then sort them 2)set up LNode *subHead = L,L->next = NULL,be L If the original header node is saved, the elements in the array can be inserted into the array in turn by using the header insertion method L After, insert all the ordered tables L The stored node element values are incrementally ordered
void LinkSort(LinkList L) { LNode *subHead = L; // Store the header node and insert the header of the ordered table L->next = NULL; // Calculate the number of nodes to facilitate the use of array storage int count = 0; while (subHead != NULL) { count += 1; L->next = subHead; subHead = subHead->next; } int *temp = (int *)malloc(sizeof(int) * count); memset(temp,0,sizeof(int)*count); subHead = L; L->next = NULL; int i; for (i = 0;i < count;i++) { temp[i] = subHead->data; subHead = subHead->next; } // Select and sort, and select the largest element in each round until the table is empty int j = 0,min; while (j < count) { min = temp[j]; for (j = 0;j < count;j++) { if (min > temp[j]) { min = temp[j]; } } // After inserting into L by head inserting method LNode *r; r->data = min; r->next = L->next; L->next = r; } L->next = NULL; }
Time complexity: O ( n 2 ) O(n^2) O(n2) space complexity: O ( n ) O(n) O(n)
Reference answer:
Written thought: 1)Waiting sequence L[1...n]At some point, the state is like this: ordered sequence L[1,...i-1],L[i],Disordered sequence L[i+1...n] 2)take L[i]Insert into ordered subsequence L[1...i-1]in
// Use the direct insertion sorting algorithm to sort void insertSort(LinkList L) { LNode *curp = L->next, // First element node *prep, // Used to identify the unordered part of the linked list // The first element node is considered to be ordered, and the disordered part starts from the second *subL = curp->next; // At first, there is only one element in the ordered part, and the next of the last element should be NULL curp->next = NULL; // Start processing the unordered part from the second element node curp = subL; // When there are nodes in the disordered part while (curp != NULL) { // curp will be inserted into the ordered part, so save its subsequent [new unordered part] first subL = curp->next; // Prepare to find the first node larger than the curp element from front to back prep = L; while (prep->next != NULL && prep->next->data < curp->data) { // The last bit of the current element is still less than curp // Ordered partial backward prep = prep->next; } // When exiting, prep is followed by the insertion position of curp /* 1,curp Is the biggest 2,prep->next Is the first node greater than curp */ // Typical insertion operation [active node to be inserted] curp->next = prep->next; prep->next = curp; // Handle the next node of the unordered part curp = subL; } }
Time complexity: O ( n 2 ) O(n^2) O(n2) space complexity: O ( 1 ) O(1) O(1)
7. The data values of all element nodes in a single linked list with header nodes are out of order. Try to write a function to delete all elements (if any) between the given two values (given as function parameters) in the list
Written thought: 1)Set the precursor node pointer and current node pointer. When traversing the appropriate node to meet the data value within the given range, delete the current node through the precursor node pointer and connect to the successor node of the current node
void delRange(LinkList L,int start,int end) { LNode *aux = L,*subHead = L->next; while (subHead != NULL) { if (subHead->data >= start && subHead->data <= end) { // Store current node LNode *P = subHead; aux->next = P->next; free(P); } else { // Point to the next node aux = subHead; subHead = subHead->next; } } }
8. Given two linked lists, write an algorithm to find the common nodes of the two linked lists
Written thought: 1)The public node is the address(Pointer)identical 2)The problem is transformed into traversing the linked list A and B,Find the first node with the same address value
LNode *findFirstNode(LinkList A,LinkList B) { // Suppose they are linked lists of leading nodes LNode *subHead = A->next; A->next = NULL; // The nodes in A linked list are compared with those in B one by one while (subHead != NULL) { LNode *head = B->next; B->next = NULL; while (head != NULL) { // If two address values are found to be the same, exit the loop and all subsequent node address values are the same if (&subHead == &head) { return subHead; } // After the comparison is not satisfied, insert the current node into B to facilitate the cycle B->next = head; } } }
Time complexity: O ( n 2 ) O(n^2) O(n2) space complexity: O ( 1 ) O(1) O(1)
9. Given a single linked list of leading nodes, set head as the head pointer, node structure as (data,next), data as the integer element and next as the pointer, and try to write the algorithm: output the data elements of each node in the single linked list in increasing order, and release the storage space occupied by the node (requirement: array is not allowed to be used as auxiliary space).
Written thought: Set precursor node pointer aux,Current working pointer subHead,L Storage header node, L->next = NULL,Using selection sorting, each round of traversal subHead Find the element with the smallest value and output it directly aux Delete the current node to free up space
void printSort(LinkList L) { while (True) { LNode *aux = L, *subHead = L->next; L->next = NULL; int min = subHead->data; while (subHead != NULL) { if (min > subHead->data) { min = subHead->data; } aux = subHead; L->next = subHead; subHead = subHead->next; } // Find node delete cout << min << ", "; LNode *del = aux->next; aux->next = del->next; free(aux); // Traverse completely and exit the loop if (L->next == NULL) { break; } } }
Time complexity: O ( n 2 ) O(n^2) O(n2) space complexity: O ( 1 ) O(1) O(1)
10. The single linked list A of A leading node is decomposed into the single linked lists A and B of two leading nodes, so that table A contains the elements with odd numbers in the original table, while table B contains the elements with even numbers in the original table, and its relative order remains unchanged.
Written thought: 1)Set pointer variable subHead = L->next,and L->next = NULL be L As a single linked list with only head nodes A,Create a new single linked list B,order B->next = NULL 2)from A,B Save the elements with odd and even numbers respectively, so you can set a count variable to insert the elements into the linked list respectively A and B Middle go 3)Insert into A and B The relative order of the elements in is unchanged, so tail interpolation can be considered
void splitLink(LinkList L) { int count = 0; // Count variable LNode *subHead = L->next; L->next = NULL; // As A linked list with only head nodes, A LNode *B; B->next = NULL; // Linked list B with only header nodes // Intermediate variable convenient for tail interpolation LNode *tail = L *band = B; while (subHead != NULL) { count += 1; // Insert tail into table A if (count % 2 == 1) { // Tail points to the subsequent node of L. after inserting the node to be inserted into r, it is tail insertion tail->next = subHead; tail = subHead; } else { band->next = subHead; band = subHead; } subHead = subHead->next; } }
Time complexity: O ( n ) O(n) O(n) space complexity: O ( n ) O(n) O(n)
11. Set C as { a 1 , b 1 , a 2 , b 2 , ... a n , b n } \{{a1,b1,a2,b2,...an,bn\}} {a1,b1,a2,b2,... an,bn} is a linear table, which is stored in the hc single linked table of the leading node. A local algorithm is designed to split it into two linear tables so that A = { a 1 , a 2 , ... a n } , B = { b n , ... b 2 , b 1 } A = \{{a1,a2,...an\}},B = \{{bn,...b2,b1\}} A={a1,a2,...an},B={bn,...b2,b1}.
Written thought: 1)Observation linked list C knowable ai(1 ≤ i ≤ n)and bj(1 ≤ j ≤ n)Alternate, and A The sequences in the table are sorted normally, and B The sequence in the table is in reverse order 2)So we know A The tail interpolation method is used in the table, B Header interpolation is used in the table 3)ai stay C Is stored in odd digits, and bj stay C Is stored in even digits, so a new variable is created count To count
void splitLink(LinkList C) { int count = 0; LNode *A,*B,*subHead = C->next; // Create two single linked tables A and B with only head nodes A->next = NULL; B->next = NULL; LNode *tail = A,*head = B; while (subHead != NULL) { count += 1; // Odd digit tail interpolation if (count % 2 == 1) { tail->next = subHead; tail = subHead; } else { // Even bit execution header interpolation subHead->next = head->next; head->next = subHead; } subHead = subHead->next; } }
Time complexity: O ( n ) O(n) O(n) space complexity: O ( n ) O(n) O(n)
12. In an incrementally ordered linear table, there are elements with the same value. If the storage method is a single linked list, the design algorithm removes the elements with the same value so that there are no duplicate elements in the table, such as ( 7 , 10 , 10 , 21 , 30 , 42 , 42 , 42 , 51 , 70 ) (7,10,10,21,30,42,42,42,51,70) (7,10,10,21,30,42,42,42,51,70) will become ( 7 , 10 , 21 , 30 , 42 , 51 , 70 ) (7,10,21,30,42,51,70) (7,10,21,30,42,51,70)
Written thought: 1)Set precursor node pointer variable aux And current node pointer variables subHead,stay subHead If it is not empty, it will be traversed all the time subHead->data and aux->data Unequal rule aux=subHead,subHead = subHead->next 2)Otherwise, delete the current node LNode *p = subHead;aux->next = subHead->next;free(p),aux and subHead unchanged
void delSameElem(LinkList L) { // Suppose L is a single linked list of leading nodes LNode *aux = L->next, *subHead = aux->next; while (subHead != NULL) { // If the value of the element behind the table is the same as that of the previous element, delete it if (subHead->data == aux->data) { LNode *P = subHead; aux->next = subHead->next; free(P); } else { aux = subHead; subHead = subHead->next; } } }
Time complexity: O ( n ) O(n) O(n) space complexity: O ( 1 ) O(1) O(1)
13. Suppose there are two linear tables arranged in the order of increasing element values, which are stored in the form of single linked list. Please write an algorithm to merge the two single linked lists into a single linked list arranged in descending order of element values, and use the nodes of the original two single linked lists to store the merged single linked list
Written thought: 1)Create variable LNode *subHead = A->next,A->next = A 1)Two single linked lists A and B They are stored in order by increasing the element value. The comparison starts from the first element. In case of a node with a small element value, the node will be placed in the node by header interpolation A After that, delete the original node and continue to merge and compare until a linked list is empty 2)Insert the elements of the remaining linked list into the header in turn A After, after the whole operation is completed A It is a single linked list sorted by decreasing element values
void addReverse(LinkList A,LinkList B) { // Suppose that single linked lists A and B are the leading nodes LNode *auxA = A, *subHeadA = A->next; LNode *auxB = B, *subHeadB = B->next; // Store the tail pointers of A and B respectively LNode *tailA = A; A->next = NULL; // Only when the two single linked lists are not empty can it be carried out all the time while (subHeadA != NULL && subHeadB != NULL) { if (subHeadA->data < subHeadB->data) { LNode *P = subHeadA; tailA->next = subHeadA; auxA->next = subHeadA->next; free(P); tailA = subHeadA; } else { LNode *P = subHeadB; tailA->next = subHeadB; auxB->next = subHeadB->next; free(P); tailA = subHeadB; } } // Insert all the remaining single linked list elements after A while (subHeadA != NULL) { LNode *P = subHeadA; tailA->next = subHeadA; auxA->next = subHeadA->next; free(P); tailA = subHeadA; } while (subHeadB != NULL) { LNode *P = subHeadB; tailA->next = subHeadB; auxB->next = subHeadB->next; free(P); tailA = subHeadB; } }
Time complexity: O ( n ) O(n) O(n) space complexity: O ( 1 ) O(1) O(1)
14. Let A and B be two single linked lists (leading nodes), in which the elements are increasing in order. An algorithm is designed to generate single linked list C from the common elements of A and B, which is required not to destroy the nodes of A and B
Written thought: 1)Set pointer subHeadA Point to single linked list A,New array temp,take A Store the element values of nodes in temp Until subHeadA End 2)Set pointer subHeadB Point to single linked list B,stay subHeadB When it is not empty, the current is judged in each round subHeadB->data Is it temp The element already exists in. If it exists, insert the element into the single linked list by tail interpolation C In, subHeadB Point to the next node
# define SIZE 20 LinkList findSameElem(LinkList A,LinkList B) { // subHeadA skips the header node of A LNode *subHeadA = A->next; int *temp = (int *)malloc(sizeof(int) * SIZE); int i = 0; while (subHeadA != NULL) { temp[i++] = subHeadA->data; subHeadA = subHeadA->next; } // The value stored by i is actually the number of elements in single linked list A int j; // Traverse single linked list B LNode *subHeadB = B->next; // Create single linked list C LNode *C = (LNode *)malloc(sizeof(LNode)); C->next = NULL; // Create tail pointer LNode *tail = C; while (subHeadB != NULL) { for (j = 0;j < i;j++) { if (subHeadB->data == temp[j]) { // Tail interpolation method tail->next = subHeadB; tail = subHeadB; } } subHeadB = subHeadB->next; } return C; }
Time complexity: O ( n 2 ) O(n^2) O(n2) space complexity: O ( n ) O(n) O(n)
Written thought: A,B Align left end of table 1)Equal elements at the left end: apply for a node and insert the end of the element into the new table; A,B All move back one bit 2)The elements at the left end are not equal: the elements with smaller values are moved one bit behind the linked list 3)Repeat 1)2),Until one of the tables is empty
// A. B linked list increment (header node) // Form A new linked list of common elements in A and B (tail insertion method) LinkList generateListWithSameNode(LinkList A,LinkList B) { LNode *subA = A->next, // Table A sub table *subB = B->next; // Table B sub table // Request header node for form C LinkList C = (LinkList)malloc(sizeof(LNode)); LNode *tailC = C, // Apply a pointer variable to the tail node for C *auxP; // Auxiliary pointer variable // There are elements in both tables while (subA != NULL && subB != NULL) { // For the same element, perform tail interpolation to C if (subA->data == subB->data) { // Application node, assignment data field auxP = (LNode *)malloc(sizeof(LNode)); auxP->data = subB->data; // Perform tail interpolation tailC->next = auxP; tailC = auxP; // Both tables are moved back one bit subB = subB->next; subA = subA->next; // The elements in table A are smaller. Because they are incremented, table A moves back one bit } else if (subA->data < subB->data) { subA = subA->next; // The elements in table B are smaller. Because they are incremented, table B moves back one bit } else { subB = subB->next; } } // Table C tail node processing tailC->next = NULL; return C; }
Time complexity: O ( l e n 1 + l e n 2 ) O(len1 + len2) O(len1+len2) space complexity: O ( m i n ( l e n 1 , l e n 2 ) ) O(min(len1,len2)) O(min(len1,len2))
15. Two Integer Sequences A = a 1 , a 2 , ... a m , B = b 1 , b 2 ... b n A = a1,a2,...am,B = b1,b2...bn A=a1,a2,... am,B=b1,b2... bn have been stored in two single linked lists. An algorithm is designed to judge whether sequence B is a continuous subsequence of sequence a.
Written thought: 1)Design a function to find the table length of a single linked table 2)if A Table length lenA less than B Table length lenB,Return directly false 3)if B yes A Continuous subsequences of, then B It must be A If a part of the list appears continuously, you can traverse the single linked list at the same time A Find the first and B When the first element is the same node, the two linked lists are compared bit by bit until B The table is empty. If there is an element with unequal values in the middle, it will be returned false,Exit the loop, otherwise the loop ends and returns true
// Calculate the table length of single linked list int CalLength(LinkList L) { // Suppose there is a head node LNode *subHead = L->next; int count = 0; while (subHead != NULL) { count++; } return count; } bool justBisAPart(LinkList A,LinkList B) { // Find the table length of single linked tables A and B int lenA = CalLength(A), lenB = CalLength(B); // If lenB is greater than lenA if (lenA < lenB) { return false; } else { bool tag = false; // Suppose tables A and B are the leading nodes LNode *subHeadA = A->next; LNode *subHeadB = B->next; // Traverse table A until you find an element with the same value as the first node element in B int i; // If B is A continuous subsequence of A, you only need to traverse lenb Lena for (i = 0;i < lenB - lenA;i++) { if (subHeadA->data == subHeadB->data) { // Only when both child tables are not empty while (subHeadA != NULL || subHeadB != NULL) { subHeadA = subHeadA->next; subHeadB = subHeadB->next; } } // After the matching is successful, the continuous subsequence will be found until the table is empty if (subHeadA == NULL || subHeadB == NULL) { tag = true; } } return tag; } }
Time complexity: O ( n ) O(n) O(n) space complexity: O ( 1 ) O(1) O(1)
16. A single linked list with header node is known, and the node structure is ( d a t a , l i n k ) (data,link) (data,link), assuming that the linked list only gives the header pointer l i s t list list. Without changing the linked list, please design an algorithm as efficient as possible to find the penultimate in the linked list k k Nodes at k locations ( k by just whole number ) (k is a positive integer) (k is a positive integer). If the search is successful, the algorithm outputs the value of the node d a t a data The value of the data field and returns 1. Otherwise, only 0 is returned
Written thought: 1)Write a function CalLength To calculate the table length of a single linked list len 2)if len than k Small, 0 is returned 3)set variable i Traverse from 0 to len-k,Output the of the last node data Value and returns 1
int CalLength(LinkList L) { int count = 0; LNode *subHead = L->link; while (subHead != NULL) { count++; } return count; } int LinkFind(LinkList L,int k) { int len = CalLength(L); if (len < k) { return 0; } else { int i = 0; LNode *subHead = L->link; while (i <= len - k) { subHead = subHead->link; } cout << subHead->data << endl; return 1; } }
Time complexity: O ( n ) O(n) O(n) space complexity: O ( 1 ) O(1) O(1)
17. Given a single linked list without head nodes, it is required that the space complexity is O ( 1 ) O(1) O(1). The following example is a ring with a ring: 5 − > ... 11 − > 5 5->...11->5 5−>...11−>5
Written thought: Traverse the nodes of the single linked list step by step, re traverse all nodes before the new node from the first node, and compare the address value of the new node with the address value before this node. If it is found to be the same, it indicates that there are links in the linked list, otherwise continue until the list is empty
void justIsCircle(LinkList L) { LNode *curP = L->next; while (curP != NULL) { // Each cycle starts with the first element LNode *head = L; // Separate linked list into rings if (&curP == &head) { cout << "Linked list with links" << endl; break; } else { while (head->next != curP) { if (&curP == &head) { cout << "Linked list with links" << endl; break; } head = head->next; } // The same ID was not found after traversal curP = curP->next; } } }
Time complexity: O ( n 2 ) O(n^2) O(n2) space complexity: O ( 1 ) O(1) O(1)
18. Save with single linked list m m m integers, and the node structure is ( d a t a , n e x t ) (data,next) (data,next), and ∣ d a t a ∣ < n ( n by just whole number ) |Data | < n (n is a positive integer) ∣ data ∣ < n (n is a positive integer). Now we need to design an algorithm with time complexity as efficient as possible. For nodes with equal absolute values in the linked list, only the first node is retained and the other nodes with equal absolute values are deleted.
Written thought: 1)You can create arrays temp,receive m Absolute value of an integer 2)i Start from 0 to traverse the single linked list, and traverse each node temp Array, found temp The subscript of the first node in the array that is the same as the absolute value of the current node, if i And subscripts are not equal, indicating that this is a node to be deleted. The precursor node is used to delete it, and temp The corresponding element value in the array is n,Until the end of the table is traversed 3)The remaining single linked list stores element nodes with different absolute values
void delAbValue(LinkList L,int n,int m) { // Create a temp array to hold the data int *temp = (int *)malloc(sizeof(int) * m); int i; // Skip over node LNode *subHead = L->next; for (i = 0;i < m;i++) { temp[i] = abs(subHead->data); subHead = subHead->next; } // Precursor node pointing to node LNode *aux = L; LNode *subHead = L->next; while (subHead != NULL) { // To count int j = 0; for (i = 0;i <= j;i++) { // If the element values are equal if (abs(subHead->data) == temp[i]) { // If the subscripts are the same, don't worry if (i != j) { // Delete the node and change the temp[i] value LNode *P = subHead; aux->next = subHead->next; temp[i] = n; free(P); } } aux = subHead; subHead = subHead->next; } } }
Time complexity: O ( n 2 ) O(n^2) O(n2) space complexity: O ( n ) O(n) O(n)
19. With a pointer L L L's acyclic two-way linked list with header nodes, except p r e d ( front drive finger needle ) PRED (precursor pointer) PRED (precursor pointer) d a t a ( number according to ) Data Data and n e x t ( after Follow finger needle ) Next (subsequent pointer) Besides the next domain, there is also an access frequency domain f r e q freq freq. Before the linked list is used, its values are initialized to zero. Once in the linked list L o c a t e ( L , x ) Locate(L,x) In the Locate(L,x) operation, the element value is x x In the node of x f r e q freq The value of the freq field is increased by 1, and the nodes in the linked list are arranged in the order of non increasing (decreasing) access frequency. At the same time, the most recently accessed nodes are ranked last among the nodes with the same frequency, so that the frequently accessed nodes are always close to the header. Try to write a document that meets the above requirements L o c a t e ( L , x ) Locate(L,x) The algorithm of Locate(L,x) operation, which is a function process and returns the address of the found node. The type is pointer type.
Written thought: 1)Create an array temp Backup access frequency domain freq 2)Write function Locate(L,x)To locate the lookup element x In the double linked list, make it freq Additive temp The element value in the array is also incremented by 1 3)Traverse the double linked list from the beginning and find the first one freq The node smaller than yourself is inserted in front of it
// Returns the subscript of the matched x LNode *Locate(LinkList L,int x) { LNode *subHead = L->next; int i; // Flag variable to judge whether there is element x in the double linked list bool tag = false; while (subHead != NULL) { if (subHead->data == x) { // Exit this cycle when found tag = true; break; } else { // When there is no match, the pointer moves backward and the count increases by 1 i++; subHead = subHead->next; } } subHead = L->next; if (!tag) { // Traversing the entire double linked list did not find x, and the entire double linked list did not move return NULL; } else { // Traverse to node i, save the node, delete the corresponding position, and connect the front and back nodes int j = 0; while (j < i) { subHead = subHead->next; } // Now is the node at i LNode *curP = subHead; // Connect its predecessor and successor curP->next = curP->pred->next; curP->next->pred = curP->pred; // Traverse from the beginning, find the first node smaller than yourself and insert it in front of it subHead = L->next; P->freq += 1; while (subHead != NULL) { if (subHead->freq > P->freq) { subHead = subHead->next; } else { // Insert P before the node and keep the continuity between nodes subHead->pred->next = P; subHead->next = P->next; } } return P; } }
Time complexity: O ( n ) O(n) O(n) space complexity: O ( 1 ) O(1) O(1)
20. Suppose that the single linked list of the leading node is used to save words. When two words have the same suffix, they can share the same suffix storage space. For example, the storage impression of "loading" and "being" is shown in the figure below.
Let str1 and str2 respectively point to the head node of the single linked list where the two words are located. The linked list structure is ∣ d a t a ∣ n e x t ∣ |data|next| ∣ data ∣ next ∣, please design an algorithm as efficient as possible in time to find out the reason s t r 1 and s t r 2 str1 and str2 The starting position of the common suffix of the two linked lists pointed to by str1 and str2 (as shown in the figure) i i Location of node i p p p). requirement:
- The basic design idea of the algorithm is given
- According to the design idea, the C or C + + or J a v a C or C + + or Java Describe the algorithm in C or C + + or Java language, and give comments on the key points
- Explain the time complexity of your algorithm
Written thought: 1)Write a function to find the length of a single linked list CalLength,Linked lists are the leading nodes 2)Separate use CalLength Find the linked list A and B Table length lenA and lenB 3)For a single linked list with a long table length, you might as well set B Yes, then B The pointer moves backward lenB - lenA position 4)Then point to A and B The pointer of the node is compared step by step. If it is not equal, it will move backward by 1 bit until it is found that the addresses of the two nodes are the same, it will return to the node and exit the loop 5)If a table is empty and no node with the same address is found, the NULL
// Calculate single linked list length function int CalLength(LinkList L) { LNode *subHead = L->next; int count = 0; while (subHead != NULL) { count++; subHead = subHead->next; } return count; } LNode *findFirstNode(LinkList A,LinkList B) { // Calculate the lengths of tables A and B respectively int lenA = CalLength(A); int lenB = CalLength(B); // Two pointers to A and B header nodes LNode *str1 = A, *str2 = B; LNode *subHeadB = B->next; LNode *subHeadA = A->next; int i = 0; // B move back if (lenA < lenB) { while (i < lenB - lenA) { subHeadB = subHeadB->next; i++; } } else { while (i < lenA - lenB) { subHeadA = subHeadA->next; } } // Both pointers move at the same time bool tag = false; while (subHeadA != NULL && subHeadB != NULL) { if (&subHeadA == &subHeadB) { LNode *curP = subHeadA; tag = true; } else { subHeadA = subHeadA->next; subHeadB = subHeadB->next; } } if (tag) { return true; } else { return NULL; } }
Time complexity: O ( l e n A + l e n B ) O(lenA + lenB) O(lenA+lenB) space complexity: O ( 1 ) O(1) O(1)
21. Set linearity table L = ( a 1 , a 2 , a 3 , ... , a n − 2 , a n − 1 , a n ) L=(a1,a2,a3,...,an-2,an-1,an) L=(a1,a2,a3,..., an − 2,an − 1,an) is saved in the single linked list of the leading node. The nodes in the linked list are defined as follows:
typedef struct node { int data; struct node* next; }NODE;
Please design a space with a complexity of O ( 1 ) O(1) O(1) and as time efficient as possible, rearrange L L L, get the linear table L = ( a 1 , a n , a 2 , a n − 1 , a 3 , a n − 2 , ... ) L=(a1,an,a2,an-1,a3,an-2,...) L=(a1,an,a2,an−1,a3,an−2,…). requirement:
- The basic design idea of the algorithm is given
- According to the design idea, the C or C + + C or C++ C or C + + language describes the algorithm, and notes are given at the key points
- Explain the time complexity of the algorithm you designed
Written thought: 1)Write a table length function CalLength 2)take L Divided into two sub tables A and B,If the table length is even, then A Before containing len/2 Elements, B After containing len/2 Elements, otherwise A Before containing len/2+1 Elements, B After containing len/2 Elements 3)yes A The table will not be operated B Table reversal 4)establish C Table, will A,B Table elements are sequentially inserted into C In the table, then C The table is the table to be found
int CalLength(LinkList L) { int count = 0; LNode *subHead = L->next; while (subHead != NULL) { // Count and move the pointer back count++; subHead = subHead->next; } return count; } // Arrange to generate a new table void remakeList(LinkList L) { LNode *C,*A,*B; C->next = NULL; A->next = NULL; B->next = NULL; int len = CalLength(L); LNode *subHead = L->next; // Counted int i = 0; LNode *tailA = A,*tailB = B; while (subHead != NULL) { // Tail interpolation if (i < len/2) { tailA->next = subHead; tailA = subHead; subHead = subHead->next; i++; } // Judge whether len is odd or even if (len % 2 == 1) { tailA->next = subHead; tailA = subHead; subHead = subHead->next; i++; } if (i > len/2 && i < len) { tailB->next = subHead; tailB = subHead; subHead = subHead->next; } } // After dividing tables A and B, perform header interpolation on table B to realize reversal LNode *curP->next = B; while (curP != NULL) { curP->next = C->next; C->next = curP; curP = curP->next; } // Now C stores the reverse linked list of B LNode *B = C->next C->next = NULL; LNode *tail = C; while (B != NULL || A != NULL) { // Execute tail interpolation tail->next = A->next; tail = A; tail->next = B->next; tail = B; } }
Time complexity: O ( n ) O(n) O(n)