permutation(permutation combination)
Permutation questions:
Set R = {r1, r2, ..., RN} is an n element to be arranged, Ri = R-{ri}; The full permutation of the elements in collection X is permutation (x), and (RI) permutation (x) represents the permutation of the prefix ri before each permutation of the fully arranged permutation (x).
The full arrangement of R can be summarized as follows:
When N=1, permutation (R) ={r},r is the only element in the set R;
When N>1, permutation (R) is composed of (R1) permutation (R1), (R2) permutation (R2), ..., (RN) permutation (RN).
Recursively defined in turn, the recursive algorithm that produces permutation (X) can be designed as follows:
Template <typename type>void permutation (Type *array, int front, int last) { //is already recursive to the final element if (front = = Las T) { //print output for (int i = 0; i < front; ++i) { cout << array[i] << "; } cout << Array[front] << Endl; return; } else { for (int i = front, I <= last; ++i) { //constant selection of an element from the subscript [front-last] element// as the beginning element of the current sequence Std::swap (Array[front], array[i]); Permutation (array, front+1, last); Std::swap (Array[front], array[i]);}}
Algorithm description :
The algorithm permutation (array, K, m) recursively produces all prefixes that are array[0:k-1], and the suffix is array[k:m] All permutations of the entire arrangement . function Call (list, 0, n-1) is generated List[0:n-1] the full array .
Algorithm Demo :
Char str[] = "ABC"; the recursive call procedure :
Summary:
Although we implemented the permutation ourselves, but the C + + STL also implemented the Std::next_permutation algorithm, in general applications, I would recommend the use of STL has been implemented in the Next_permutation, After all, the quality of STL code is very high, and the speed is not inferior to our implementation;
Insert Sort
The insertion sort is the fastest of the low-level sort (the bubble/select/insert sort efficiency is O (n^2)), but with the quick sort (nlogn), merge sort (NLOGN) or there is a certain gap in ⊙﹏⊙ b Khan!
Algorithm idea:
Continuously select an element from an unordered sequence to insert into an already sequenced sequence (of course, there is a selection of the insertion position: Select a position, the element before the position is smaller than the element, the element is larger than the element), similar to the real life of the landlord's touch and arrange process.
//implementation and resolution/** description : outer: First unsorted element inner: Search for the first element that is less than TMP tmp: used to stage the first unordered element */template <typename type>void Insertionsort (T Ype *begin, Type *end) throw (std::range_error) {if (begin = end) | | (begin = NULL) | | (end = NULL)) Throw Std::range_error ("pointer unavailable"); Suppose that the first element is already sorted for (type *outer = begin+1; outer < end; ++outer) {Type tmp = *outer; The first unsorted element is staged with Type *inner = outer; Inner constantly looking for a location (* (INNER-1) <= tmp),//Make Tmp->*inner (TMP saved values inserted into inner position) while (Inner > begin & & * (INNER-1) > tmp) {*inner = * (inner-1); The element moves back--inner; Pointer move forward} *inner = tmp; Inserts an element into the sorted sequence}}template <typename iter>void insertionsort (ITER begin, Iter end) {return Insertionsort (& *b Egin), & (*end));}
The origin of the/**insertionsort_2 algorithm: You can use *begin (the first element of the sequence) as the Sentinel, so that you can omit the inner > begin judgment in line 15th of Insertionsort, But the price to pay is that the location pointed to by begin can no longer store useful data and can only be used as a sort of sentinel--and space-changing time (personal feeling is not necessary ...) */template <typename type>void insertionsort_2 (Type *begin, type *end) throw (std::range_error) { if (begin = = End) | | (begin = NULL) | | (end = NULL)) Throw Std::range_error ("pointer unavailable"); for (Type *outer = begin+2; outer < end; ++outer) { *begin = *outer; Type *inner = outer; Because *begin cannot > *begin, the loop must exit while (* (inner-1) > *begin) { * (inner) = * (inner-1); --inner; } *inner = *begin; }}
Attached-permutation and std::next_permutation test code
int main () { vector<char> str; for (char ch = ' a '; Ch <= ' C '; ++ch) str.push_back (CH); Permutation (& (*str.begin ()), 0, 2); cout << "----------" << Endl; typedef vector<char>::iterator ITER_TYPE; Do {for (iter_type iter = Str.begin (); ITER! = Str.end (); ++iter ) cout << *iter << '; cout << Endl; } while (Std::next_permutation (Str.begin (), Str.end ())); return 0;}
Data Structure Basics (3)--permutation & Insert Sort