1
+ #pragma once
2
+ #ifndef MS_ALGORITHM_H
3
+ #define MS_ALGORITHM_H
4
+
5
+ #include " walker.h"
6
+ #include " internal.h"
7
+
8
+ typedef int int_type;
9
+ typedef size_t size_type;
10
+
11
+
12
+ // _MS_advance for input_walker & forward_walker
13
+ template <typename InputWalker,typename Distance>
14
+ inline void _MS_advance (InputWalker& _Walker,Distance _Dis,input_iterator_tag){
15
+ _MSJUDGE (_Dis<0 ," negative advance of non-bidirectional walker" );
16
+ while (_Dis--){
17
+ ++_Walker;
18
+ }
19
+ }
20
+
21
+ // _MS_advance for bidirectional_walker
22
+ template <typename BidirectionalWalker,typename Distance>
23
+ inline void _MS_advance (BidirectionalWalker& _Walker,Distance _Dis,bidirectional_iterator_tag){
24
+ if (_Dis>=0 ){
25
+ while (_Dis--){
26
+ ++_Walker;
27
+ }
28
+ }
29
+ else {
30
+ while (_Dis++){
31
+ --_Walker;
32
+ }
33
+ }
34
+ }
35
+
36
+ // _MS_advance for random_access_walker
37
+ template <typename RandomAccessWalker,typename Distance>
38
+ inline void _MS_advance (RandomAccessWalker& _Walker,Distance _Dis,random_access_iterator_tag){
39
+ _Walker+=_Dis;
40
+ }
41
+
42
+ // MS_advance
43
+ template <typename InputWalker,typename Distance>
44
+ inline void MS_advance (InputWalker& _Walker,Distance _Dis){
45
+ _MS_advance (_Walker,_Dis,walker_traits<InputWalker>::iterator_category ());
46
+ }
47
+
48
+
49
+
50
+ // MS_find
51
+ template <class InputWalker ,class T >
52
+ InputWalker MS_find (InputWalker _First,InputWalker _Last,const T& _Val){
53
+ while (_First!=_Last) {
54
+ if (*_First==_Val){
55
+ return _First;
56
+ }
57
+ ++_First;
58
+ }
59
+ return _Last;
60
+ }
61
+
62
+
63
+ // MS_find_if
64
+ template <class InputWalker ,class UnaryPredicate >
65
+ InputWalker MS_find_if (InputWalker _First,InputWalker _Last,UnaryPredicate _Pred){
66
+ while (_First!=_Last) {
67
+ if (_Pred (*_First)) return _First;
68
+ ++_First;
69
+ }
70
+ return _Last;
71
+ }
72
+
73
+
74
+
75
+ template <typename BidirectionalWalker,typename Compare>
76
+ void _MS_insertsort (BidirectionalWalker _First,BidirectionalWalker _Last,Compare _Pred){
77
+ for (BidirectionalWalker W2=_First+1 ;W2<=_Last-1 ;++W2){
78
+ typename walker_traits<BidirectionalWalker>::value_type Temp=*W2;
79
+ BidirectionalWalker W1=W2-1 ;
80
+ while (W1>=_First&&_Pred (Temp,*W1)){// ----------------
81
+ // while(W1>=_First&&!(_Pred(*W1,Temp)||*W1==Temp)){//----------------
82
+ *(W1+1 )=*W1;
83
+ if (W1==_First){
84
+ break ;
85
+ }
86
+ --W1;
87
+ }
88
+ if (W1==_First&&_Pred (Temp,*W1)){// ----------------
89
+ // if(W1==_First&&!(_Pred(*W1,Temp)||*W1==Temp)){//----------------
90
+ *W1=Temp;
91
+ }
92
+ else {
93
+ *(W1+1 )=Temp;
94
+ }
95
+ }
96
+ }
97
+
98
+ template <typename BidirectionalWalker,typename Compare>
99
+ typename walker_traits<BidirectionalWalker>::reference _MS_mid3 (BidirectionalWalker _First,BidirectionalWalker _Last,Compare _Pred){ // 基准的取法:三者取中
100
+ BidirectionalWalker Left=_First;
101
+ BidirectionalWalker Mid=_First+(_Last-_First)/2 ;
102
+ BidirectionalWalker Right=_Last-1 ;
103
+ typedef typename walker_traits<BidirectionalWalker>::value_type value_type;
104
+ value_type Left_v=*Left;
105
+ value_type Mid_v=*Mid;
106
+ value_type Right_v=*Right;
107
+ value_type Temp_v=(_Pred (Left_v,Mid_v)?(_Pred (Mid_v,Right_v)?Mid_v:_Pred (Left_v,Right_v)?Right_v:Left_v):(_Pred (Mid_v,Right_v)?(_Pred (Left_v,Right_v)?Left_v:Right_v):Mid_v));// ----------------
108
+ if (!(_Pred (Mid_v,Temp_v)||_Pred (Temp_v,Mid_v))){
109
+ // if(Mid_v==Temp_v){
110
+ *Mid=*Left;
111
+ *Left=Temp_v;
112
+ return Temp_v;
113
+ }
114
+ if (!(_Pred (Right_v,Temp_v)||_Pred (Temp_v,Right_v))){
115
+ // if(Right_v==Temp_v){
116
+ *Right=*Left;
117
+ *Left=Temp_v;
118
+ return Temp_v;
119
+ }
120
+ return Temp_v;
121
+ }
122
+
123
+ template <typename BidirectionalWalker,typename Compare>
124
+ BidirectionalWalker _MS_partition (BidirectionalWalker _First,BidirectionalWalker _Last,Compare _Pred){ // 划分函数
125
+ BidirectionalWalker W1=_First;
126
+ BidirectionalWalker W2=_Last-1 ;
127
+ if (_First<(_Last-1 )){
128
+ typename walker_traits<BidirectionalWalker>::value_type Pivot=_MS_mid3 (_First,_Last,_Pred);
129
+ while (W1<W2){
130
+ while (W1<W2&&!(_Pred (*W2,Pivot))){// ----------------
131
+ --W2;
132
+ }
133
+ *W1=*W2;
134
+ while (W1<W2&&!(_Pred (Pivot,*W1))){// ----------------
135
+ ++W1;
136
+ }
137
+ *W2=*W1;
138
+ }
139
+ *W1=Pivot;
140
+ }
141
+ return W1;
142
+ }
143
+
144
+ template <typename BidirectionalWalker,typename Compare>
145
+ void _MS_quicksort (BidirectionalWalker _First,BidirectionalWalker _Last,Compare _Pred){
146
+ size_type Dis=0 ;
147
+ BidirectionalWalker Temp=_First;
148
+ while (Temp!=_Last&&Dis<11 ){
149
+ ++Temp;
150
+ ++Dis;
151
+ }
152
+ if (Dis<=10 ){
153
+ _MS_insertsort (_First,_Last,_Pred);
154
+ }
155
+ /* if(static_cast<size_type>(_Last-_First)<=10){
156
+ _MS_insertsort(_First,_Last,_Pred);
157
+ }*/
158
+ else {
159
+ BidirectionalWalker Pos=_MS_partition (_First,_Last,_Pred);
160
+ _MS_quicksort (_First,Pos,_Pred);
161
+ _MS_quicksort (++Pos,_Last,_Pred);
162
+ }
163
+ }
164
+
165
+ // MS_sort
166
+ template <typename BidirectionalWalker>
167
+ void MS_sort (BidirectionalWalker _First,BidirectionalWalker _Last){
168
+ _MS_quicksort (_First,_Last,_MS_Less<>());
169
+ }
170
+
171
+ template <typename BidirectionalWalker,typename Compare>
172
+ void MS_sort (BidirectionalWalker _First,BidirectionalWalker _Last,Compare _Pred){
173
+ _MS_quicksort (_First,_Last,_Pred);
174
+ }
175
+
176
+
177
+ #endif // !MS_ALGORITHM_H
0 commit comments