I. Question
Consider such a sorting problem, that is, you cannot accurately know the exact size of each number in the sorting. for each number, we only know that it falls within a certain range on the real axis. that is, the given n closed intervals in the form of [ai, BI], where Ai is less than or equal to bi. the goal of the algorithm is to perform fuzzy-sort for these intervals, that is, to generate a sort for each interval. <I1,
I2, I3, I4 ,... In>, so that there is a CJ in [ai,
BI], satisfying C1 ≤ C2 ≤... ≤ CN.) Design an algorithm for Fuzzy sorting of N intervals. Your algorithm should have a general structure of the algorithm, which can quickly sort the left endpoint (that is, each AI To improve the running time. (as the number of overlapping intervals increases, sorting of intervals becomes more and more easy. Your algorithm should be able to make full use of this overlap .) b) Proof:
Generally, your algorithm runs at O (N * lgn) intervals, but when all the intervals overlap, the expected run time is O (n) (that is, when there is a value of X, so that all I have X in [ai, BI]). your algorithms should not explicitly check this situation, but should naturally improve performance as the number of overlaps increases.
Ii. Thinking
Based on the Division idea of the Quick Sort, a certain element is used as the primary element to divide the region into three segments. The first segment is smaller than the principal component, and the second segment is equal to the principal component.
The focus is on Division. If the intervals overlap, they will be treated as equal, and the public part will be extracted for further division.
A. End <B. Start => A <B
A. Start> B. End => A> B
Other cases => A = B
To avoid situations such as (), We need to extract the common factor and update the principal element when the principal element is equal)
The specific explanations are in the code.
Iii. Code
[CPP]
View plaincopyprint?
- # Include <iostream>
- Using namespace STD;
- Struct Node
- {
- Int start;
- Int end;
- Bool operator <(const node & B) const
- {
- Return end <B. Start;
- }
- Bool operator = (const node & B) const
- {
- Return (end> = B. Start) & (start <= B. End );
- }
- Bool operator> (const node & B) const
- {
- Return Start> B. end;
- }
- };
- // Division results: 0-> A is smaller than the principal component, A + 1-> B-1 is equal to the principal component, B-> length_a is greater than the principal component
- Struct divid
- {
- Int;
- Int B;
- };
- Node A [11];
- Int length_a = 10;
- // Display the results in three rows
- Void print (divid D)
- {
- Int I = 1;
- If (D. A> 0)
- {
- For (I = 1; I <= d. a; I ++)
- Cout <'(' <A [I]. Start <',' <A [I]. End <")";
- Cout <Endl;
- I = D. A + 1;
- }
- If (d. B> 0)
- {
- For (; I <D. B; I ++)
- Cout <'(' <A [I]. Start <',' <A [I]. End <")";
- Cout <Endl;
- I = D. B;
- }
- If (I <= length_a)
- {
- For (; I <= length_a; I ++)
- Cout <'(' <A [I]. Start <',' <A [I]. End <")";
- Cout <Endl;
- }
- Cout <Endl;
- }
- // Exchange
- Void Exchange (node & A, node & B)
- {
- Node temp;
- Temp =;
- A = B;
- B = temp;
- }
- // Division is important
- Divid partition (node * a, int P, int R)
- {
- // Take any element as the primary element
- Node x = A [R];
- Int I = p-1, j = R + 1, K = P;
- While (k <= R & K <j)
- {
- // If it is less than the principal component, switch to the front
- If (A [k] <X)
- {
- I ++;
- Exchange (A [I], a [k]);
- K ++;
- }
- // If the value is greater than, it is switched to the end.
- Else if (a [k]> X)
- {
- J --;
- Exchange (A [J], a [k]);
- // K ++ is not allowed here, because the exchanged elements may be greater than the principal element.
- }
- Else
- {
- // If they are equal, they are not exchanged, but the common factor must be extracted.
- X. End = min (X. End, a [K]. End );
- X. Start = max (X. Start, a [K]. Start );
- K ++;
- }
- }
- // Return the division result
- Divid ret = {I, j };
- If (Ret. A <p) ret. A =-1;
- If (Ret. B> r) ret. B =-1;
- Print (RET );
- Return ret;
- }
- Void quicksort (node * a, int P, int R)
- {
- If (P> = r)
- Return;
- // Divide the array into three segments
- Divid q = partition (A, P, R );
- // If the first segment exists, sort the first segment
- If (Q. A> 0)
- Quicksort (A, p, q. );
- // If the third segment exists, sort the third segment
- If (Q. B> 0)
- Quicksort (A, Q. B, R );
- }
- Int main ()
- {
- Int I, N;
- Cin> N;
- Length_a = N;
- // Init data by random
- For (I = 1; I <= length_a; I ++)
- {
- A [I]. Start = rand () % 100;
- A [I]. End = rand () % 100;
- If (A [I]. Start> A [I]. End)
- Swap (A [I]. Start, a [I]. End );
- }
- Divid d = {-1,-1 };
- Print (d );
- // Sort
- Quicksort (A, 1, length_a );
- Return 0;
- }
# Include <iostream> using namespace STD; struct node {int start; int end; bool operator <(const node & B) const {return end <B. start;} bool operator = (const node & B) const {return (end> = B. start) & (start <= B. end);} bool operator> (const node & B) const {return start> B. end ;}}; // partition result: 0-> A is smaller than principal component, A + 1-> B-1 is equal to Principal Component, B-> length_a is greater than Principal Component struct divid {int; int B ;}; node A [11]; int length_a = 10; // display void print (divid d) {int I = 1; if (D. a> 0) {for (I = 1; I <= D. a; I ++) cout <'(' <A [I]. start <',' <A [I]. end <")"; cout <Endl; I = D. A + 1;} If (D. b> 0) {for (; I <D. b; I ++) cout <'(' <A [I]. start <',' <A [I]. end <")"; cout <Endl; I = D. b;} if (I <= length_a) {for (; I <= length_a; I ++) cout <'<A [I]. start <',' <A [I]. end <")"; cout <Endl ;}cout <Endl ;}// exchange void Exchange (node & A, node & B) {node temp; temp = A; A = B; B = temp;} // Division is the key divid partition (node * a, int P, int R) {// take any element as the primary node x = A [R]; int I = p-1, j = R + 1, K = P; while (k <= R & K <j) {// if it is smaller than the principal component, switch to the front if (a [k] <X) {I ++; exchange (A [I], a [k]); k ++;} // if the value is greater than, switch to the following else if (a [k]> X) {J --; exchange (A [J], a [k]); // here K ++ is not allowed, because the exchanged elements may be greater than the principal element} else {// if they are equal, do not exchange, but extract the public factor X. end = min (X. end, a [K]. end); X. start = max (X. start, a [K]. start); k ++; }}// returns the division result divid ret = {I, j}; If (Ret. A <p) ret. A =-1; if (Ret. b> r) ret. B =-1; print (RET); return ret;} void quicksort (node * a, int P, int R) {If (P> = r) return; // divide the array into three segments: divid q = partition (A, P, R); // if the first segment exists, sort the first segment if (Q. a> 0) quicksort (A, P, Q. a); // if the third segment exists, sort the IF (Q. b> 0) quicksort (A, Q. b, R) ;}int main () {int I, n; CIN> N; length_a = N; // init data by randomfor (I = 1; I <= length_a; I ++) {A [I]. start = rand () % 100; A [I]. end = rand () % 100; if (a [I]. start> A [I]. end) Swap (A [I]. start, a [I]. end) ;}divid D ={-1,-1 }; print (d); // sortquicksort (A, 1, length_a); Return 0 ;}
Reprinted from: http://blog.csdn.net/mishifangxiangdefeng/article/details/7681109