Author: Source: September 4, 2006
13. Put the sentry in R[n], put the sorted records in R[0..n- 1], and rewrite the direct insertion sorting algorithm.
Solution:
The algorithm for rewriting is as follows:
void InsertSort(SeqList R)
{//Insert and sort records r [0...n- 1] in ascending order.
int i,j;
for(I = n-2; I & gt=0; I-)//Insert R[n-2]..R[0] are in the ordered area in turn.
if(R[i]。 key & gtR[i+ 1]。 Key) // If not, R[i] remains unchanged.
{
R[n]= R[I]; j = I+ 1; //R[n] is a sentry
Do{ // Find the insertion position in the ordered area from left to right.
R[j- 1]= R[j]; //Move records with keywords less than R[i]. The key is on the right.
j++;
}while(R[j].key & ltR[n]。 key]);
R[j- 1]= R[n]; //Insert R[i] into the correct position.
}//endif
}//InsertSort。
14. Use single linked list as storage structure to realize direct insertion sorting algorithm.
Solution:
#define int KeyType // define KeyType as int type.
Typedef structure node {
KeyType key; //Keyword field
Other information types; //Other information fields,
Pointer field in the structure node * next// linked list
} RecNode// Record node type
Typedef RecNode * LinkList///A single linked list is represented by LinkList.
Voidinsertport (linked list header)
{//A direct insertion sorting algorithm for chained storage structures, where head is a single linked list with the leading node as the unit.
RecNode *p,*q,* s;
If ((head->; Next)&&(Head-> Next-> Next)//When the number of nodes in the table is greater than 1.
{
p = head-& gt; Next-> Next; //p points to the second node.
head->; next = NULL
Q = head; //Point to the preceding node of the insertion position.
while(p)& amp; & (q->; Next)&&(p->; key & ltq->; Next-> Key)
q = q-& gt; Next;
If (p)
{ s = p; p = p-& gt; Next; //Remove the node to be inserted.
s-& gt; next = q-& gt; Next; //Insert the appropriate position after the Q node.
q->; next = s;
}
}
}
15. Design an algorithm to rearrange the array in the shortest possible time and put all negative keywords before all non-negative keywords. Please analyze the time complexity of the algorithm.
Solution:
Because only negative keywords need to be ranked first, there is no accurate sorting order, so this algorithm adopts the method of scanning at both ends, just like the method used in quick sorting. When the left side scans to a positive number, stop scanning to the right side, and when it encounters a negative number, exchange with the current record on the left side, so that sorting can be completed in one trip.
Invalid resort (SeqList R)
{//Rearrange the array so that the negative keyword comes first.
int i= 1,j = n; //the array is stored in r [1...n]
While (I<j)//I <; J indicates that the scan has not been completed.
{ while(I & lt; Johnson & Johnson company & ampR[i]。 Key & lt0) // If a negative number is encountered, continue scanning.
i++;
R[0]= R[I]; //R[0] is an auxiliary space.
While (I< Johnson & Johnson Company. & ampR[j]。 Key & gt=0)// If a positive number is encountered, continue to scan to the left.
j-;
R[i++]= R[j]; R[j-]= R[0]; //Swap the current two elements and move the pointer.
}//End time
}//Resort
In any case, the number of comparisons in this algorithm is n (each element is 0) and the number of exchanges is less than n/2. Generally speaking, the time complexity is O(n).
* 16. Write a two-way bubble sorting algorithm, that is, change the scanning direction alternately in the sorting process.
Solution:
The algorithm is as follows:
Void bubble sorting (SeqList R)
{//r [1...n] is the file to be sorted, and the bidirectional scanning bubble sorting is adopted.
int i,j,k;
Boolean exchange; //exchange labels
I = n; j = 1;
Exchange = true;
while(I & gt; j)& amp; & (exchange)
{ k = I- 1; Exchange = false;
while(k & gt; =j)// Scan from bottom to top
{ if(r[k]& gt; r[k+ 1])
{ r[0]= r[k]; r[k]= r[k+ 1]; r[k+ 1]= r[k]; Exchange = true; //exchange
}//endif
k-;
}//End time
If (exchange)
{ exchange = FALSE
j++; k = j+ 1;
while(k & lt; =i)// Scan from top to bottom
{ if(r[k]& lt; r[k- 1])
{ r[0]= r[k]; r[k]= r[k- 1]; r[k- 1]= r[k]; Exchange = true; //exchange
}//endif
k++;
} end time
I-;
}//endif
} end time
}//endsort
17. The following is a pseudo-code algorithm for top-down bubble sorting. lastExchange is used to record the position of the last element exchanged in each scan, which is used as the control value for the termination of the next sorting cycle. Please write a bubble sorting algorithm with bottom-up scanning.
void BubbleSort(int A[],int n)
//Let A[0..n- 1] be an integer vector.
int lastExchange,j,I = n- 1;
while(I & gt; 0)
last exchange = 0;
for(j = 0; J< me; J++)// Scan a [0 ... i] from top to bottom.
if(A[j+ 1]& lt; A[j]){
Exchange A[j] and a [j+1];
last exchange = j;
}
I = lastExchange// Set I as the last swap location.
}//End time
}//BubbleSort
Solution: The algorithm is as follows:
void BubbleSort(int A[],int n)
//Let A[0..n- 1] be an integer vector.
int lastExchange,j,I = 0;
While (I & ltN) // This is very important. If you don't change it to this, the algorithm will loop indefinitely.
last exchange = n;
for(j = n- 1; J> me; J-)// Scan A [0 ... i] from bottom to top.
if(A[j- 1]& lt; A[j]){
Exchange A[j] and a [j-1];
last exchange = j;
}
I = lastExchange// Set I as the last swap location.
}//End time
}//BubbleSort
18. To rewrite the quick sort, you need to select three divided benchmark records; If the interval length of the current sort is less than or equal to 3, the sort is directly inserted without division.
Solution:
The rewritten algorithm is as follows:
Void quick sort (SeqList R, int low, int high)
{//Sort R [low ... high] quickly
int pivotpos
If (high-low < = 2)//If there are less than 3 elements in the current area,
{//Perform direct insert sorting.
InsertSort(R,low,high);
}
other
{
pivot pos = mid partition(R,low,high);
QuickSort(R,low,pivot pos- 1);
QuickSort(R, pivotpos+ 1, high);
}
}//Quick sort
int mid partition(seq list R,int i,int j)
{//Based on the laws of the three.
if(R[(i+j)/2]。 key & gtR[i]。 Key)
{exchange R[(i+j)/2] and r [I]; }
if(R[i]。 key & gtR[j]。 Key)
{exchange R[i] and r [j]; }
if(R[i]。 Key) & ltR[(i+j)/2]. Key)
{exchange R[i] and r [(I+J)/2]; }
//The above three if statements make the key value of the first record in the interval become the middle value of the three keys.
Return part (r, i, j); //So we can still use the original partition algorithm.
}
19. For a given j( 1≤j≤n), it is required to find the record at the j-th position in the unordered record area R[ 1] (that is, to find the j-th smallest element in the unordered set), and try to use the division idea of quick sorting to write an algorithm to realize the above search operation.
A:
Quick sort of int (SeqList R, int j, int low, int high)
{//Sort R [low ... high] quickly
Int pivotpos// The position of the divided benchmark record.
If (low < high) {//Sort only when the interval length is greater than 1
pivotpos=Partition(R,low,high); //Divide R[ low ... high]
If (pivotpos==j) returns r [j];
else if(pivot pos & gt; j) return(R,j,low,pivot pos- 1);
Else returns quicksort(R, j, pivotpos+ 1, high);
}
}//Quick sort
20. Write a direct selection sorting algorithm with a single linked list as the storage structure.
A:
#define int KeyType // define KeyType as int type.
Typedef structure node {
KeyType key; //Keyword field
Other information types; //Other information fields,
Pointer field in the structure node * next// linked list
} RecNode// Record node type
Typedef RecNode * LinkList///A single linked list is represented by LinkList.
Void selectsort (linked list header)
{RecNode *p,*q,* s;
if(head-& gt; Next)&&(Head-> Next-> Next)
p = head-& gt; Next; //p points to the predecessor of the largest element in the current sort order.
while(p->; Next)
{ q = p-& gt; Next; s = p;
while(q)
{ if(q-& gt; key & lts-& gt; key)s = q;
q = q-& gt; Next;
}//End time
Exchange data between s node and p node;
p = p-& gt; Next;
}//End time
}//endif
}//endsort
2 1. Write a heapInsert(R, key) algorithm, and insert keywords into the heap R to ensure that it is still a heap after inserting R. Tip: a description of the length attribute should be added to the heap R (that is, the type description of the SeqList defined in this chapter should be rewritten to include the length field); Insert the key into the tail of the existing element in R (that is, the length of the original heap plus the position 1, and the length of the inserted heap plus 1), and then adjust it from bottom to top to make the inserted keyword satisfy the attribute. Please analyze the time of algorithm.
A:
#define n 100// Assume that the length of the file is as long as possible.
Typedef int KeyType// defines KeyType as int type.
Typedef structure node {
KeyType key; //Keyword field
Other information types; //Other information fields,
} Rectype// Record node type
Typedef structure {
Rectype data [n]; //Space for storing records
Int length; //file length
} seqlist
void heapInsert(seqlist *R,KeyType key)
{//The original heap element is in r->; data[ 1]~ R-& gt; Data [r->; Length],
//Insert the new keyword key into r-> Data [r->; Length+1] position,
//with r-> Data[0] is the auxiliary space, and it is adjusted as a heap (here set as a big root heap).
Int large//large points to the one with larger keyword among the left and right child nodes of the adjustment node.
Int is low and high; //low and high point to the first and last record of the heap to be adjusted, respectively.
int I;
r-& gt; Length++; r-& gt; Data [r->; Length]. Key = key// Insert a new record
for(I = R-& gt; Length/2; I>0; I-)// Build a heap
{
Low = I;; Height = R-& gt;; Length;
r-& gt; Data [0]. key = R-& gt; Data [low]. Key; //R-& gt; Data[low] is the currently adjusted node.
For (large = 2 * low; Large size & lt= high; large*=2){
//If large & gt high means r-> The data [low] is a leaf, and the adjustment is over;
//Otherwise, point the big pointer to r->; Left child of data [low]
if(large & lt; Gao & amp& ampr-& gt;; The data is [large]. key & ltr-& gt; Data [big+1]. Key)
Big++; //If r-> The right child of data [low] exists.
//and the keyword is greater than the left brother, make large points to it.
if(R-& gt; Data [0]. key & ltr-& gt; The data is [large]. Key)
{ R-& gt; Data [low]. key = R-& gt; The data is [large]. Key;
Low = large; //Point the low point to the new adjustment node.
}
Else break// The current adjustment node is not less than the keyword of its child nodes, and the adjustment is completed.
}//End
r-& gt; Data [low]. key = R-& gt; Data [0]. Key; //Put the adjusted node in the last position.
The end of}//
} heap insert end
Algorithm analysis:
If the file length is n, the algorithm needs to be adjusted n/2 times, and the total time complexity is similar to that of the initial heap. The worst time complexity is O(nlgn) and the auxiliary space is O( 1).
22. Write a heap construction algorithm: start from an empty heap, read in the elements in turn, call the heap insertion algorithm in the above question, and insert the elements into the heap.
A:
void BuildHeap(seqlist *R)
{
KeyType key;
r-& gt; Length = 0; //Generate an empty heap
Scanf("%d ",&key); //Set MAXINT as an impossible keyword.
And (key! =MAXINT)
{
heapInsert(R,key);
Scanf("%d ",&key);
}
}
23. Write a heap deletion algorithm: HeapDelete(R, i), delete R[i] from the heap, and analyze the algorithm time. Suggestion: firstly, exchange R[i] with the last element in the heap, reduce the heap length by 1, and then adjust it downward from position I to meet the heap properties.
A:
void HeapDelete(seqlist *R,int i)
{//The original heap element is in r->; data[ 1]~ R-& gt; Data [r->; Length],
//put R-& gt; Data [i] is deleted, that is, r->; Data [r->; Length] in r-> Aft that data [i],
//put R-& gt; Subtract 1 from the length, and then adjust the heap.
//with r-> Data[0] is the auxiliary space, and it is adjusted as a heap (here set as a big root heap).
Int large//large points to the one with larger keyword among the left and right child nodes of the adjustment node.
Int is low and high; //low and high point to the first and last record of the heap to be adjusted, respectively.
int j;
If (I>R->; Length)
Error ("No such node");
r-& gt; Data [i]. key = R-& gt; Data [r->; Length]. Key;
r-& gt; Length-; r-& gt; Data [r->; Length]. Key = key// Insert a new record
for(j = I/2; j & gt0; J-)// Build a heap
{
Low = j;; Height = R-& gt;; Length;
r-& gt; Data [0]. key = R-& gt; Data [low]. Key; //R-& gt; Data[low] is the currently adjusted node.
For (large = 2 * low; Large size & lt= high; large*=2){
//If large & gt high means r-> The data [low] is a leaf, and the adjustment is over;
//Otherwise, point the big pointer to r->; Left child of data [low]
if(large & lt; Gao & amp& ampr-& gt;; The data is [large]. key & ltr-& gt; Data [big+1]. Key)
Big++; //If r-> The right child of data [low] exists.
//and the keyword is greater than the left brother, make large points to it.
if(R-& gt; Data [0]. key & ltr-& gt; The data is [large]. Key)
{ R-& gt; Data [low]. key = R-& gt; The data is [large]. Key;
Low = large; //Point the low point to the new adjustment node.
}
Else break// The current adjustment node is not less than the keyword of its child nodes, and the adjustment is completed.
}//End
r-& gt; Data [low]. key = R-& gt; Data [0]. Key; //Put the adjusted node in the last position.
The end of}//
} heap delete ends
24. Assuming that the elements in two single linked lists are arranged in ascending order, try to write an algorithm to merge these two ordered linked lists into one single linked list arranged in ascending order. The algorithm should use the original linked list node space.
A:
Typedef structure node {
KeyType key; //Keyword field
Other information types; //Other information fields,
Pointer field in the structure node * next// linked list
} RecNode// Record node type
Typedef RecNode * LinkList///A single linked list is represented by LinkList.
Invalid merge sort (linked list la, linked list lb, linked list lc)
{RecNode *p,*q,*s,* r;
lc = la
P = la//p is the scanning pointer of la table, pointing to the previous position of the node to be compared.
Q=lb- > next; //q is the scanning pointer of the lb table, pointing to the node to be compared.
while(p->; Next)&&(ask)
If (p->; Next-> key & lt= q->; Key)
p = p-& gt; Next;
else { s = q; q = q-& gt; Next;
s-& gt; next = p-& gt; Next; p->; next = s; //After inserting the S node into the P node,
p = s; }
If (! p->; Next) p-> next = q;
Free (pounds);
}
25. Let the vector A[0..n- 1] contain n different integers, and the value of each element is between 0 and n- 1. Try to write an algorithm with time O(n) to sort vector A, and the result can be output to another vector B[0..n- 1].
A:
sort(int *A,int *B)
{//Sort the vector A and send it to the vector B..
int I;
for(I = 0; I< = n-1; i++)
b[A[I]]= A[I];
}
*26. Write a cardinal sorting algorithm for a group of English words arranged in dictionary order. Let all words consist of capital letters, and the longest word has d letters. Tip: All words with a length less than d letters should be filled with spaces at the end. When sorting, 27 boxes should be set, which correspond to spaces respectively. A, B...z are respectively.
A:
# defineysize10//Set the keyword digits d= 10.
# Define radix 27 // radix rd is 27.
Typedeffrectype data type; //Change the data type of the node in the queue to RecType.
Typedef structure node {
char key[KeySize]; //Keyword field
Other information types; //Other information fields,
} RecType// Record node type
typedef RecType seqlist[n+ 1];
Void radius sorting
{
Link queue B[ radix];
int I;
for(I = 0; I< cardinal number; I++)// box is empty.
init queue(& amp; b[I]);
for(I = KeySize- 1; I & gt=0; I-){// Sort the D-trip box from low to high.
Distribute(R,B,I); //The first KeySize-i transfer allocation
Collect(R,B); //The first KeySize-i set
}
}
void Distribute(seqlist R,LinkQueue B[],int j)
{//According to the j-th component allocation of the keyword, the box at the beginning is empty.
int I;
j = KeySize-j; //Determine the position of the keyword from the low order.
for(I = 0; I & ltn;; I++) // Scan R[i] in turn and box it.
if (R[i]。 Key [j]-'a' > 26)
Queue (& ampB[0], r [I]); //Record the j th keyword space in the 0 th queue.
Otherwise, queue up (& ampB[0], R[R[i]. key[j]-' A '+ 1]);
}
void Collect(seqlist R,LinkQueue B[])
{
//Collect the records in each non-empty box in turn. After this process, all boxes are empty.
int i,j;
for(j = 0; J< cardinal number; j++)
And (! The queue is empty (& ampB[j])
R[i++]= dequeue (& ampb [j]); //Output dequeue records to R[i] in turn.
}