Single linked list partial pseudo code

Keywords: Algorithm data structure linked list

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)

Posted by clang on Mon, 20 Sep 2021 10:01:31 -0700