00001 #ifndef MMANN_SEARCH_ALGORITHMS_H
00002 #define MMANN_SEARCH_ALGORITHMS_H
00003
00011
00012 #include "CompareAlgorithms.h"
00013
00021 template <class Datatype>
00022 Datatype* BSearch(Datatype* Key, Datatype* Base, int Size, ACompareNodesAlgorithm<Datatype, void>* Compare)
00023 {
00024 if (Size == 0)
00025 return NULL;
00026
00027 int Middle = Size/2;
00028 int CompareValue = Compare->Compare(Key, &Base[Middle], NULL);
00029 if (CompareValue == 0)
00030 {
00031 return &Base[Middle];
00032 }
00033 else if (CompareValue < 0)
00034 {
00035 return BSearch<Datatype>(Key, Base, Middle, Compare);
00036 }
00037 else if (CompareValue > 0)
00038 {
00039 Datatype* NewBase = &(Base[Middle+1]);
00040 return BSearch<Datatype>(Key, NewBase, (Size-1)/2, Compare);
00041 }
00042
00043 return NULL;
00044 }
00045
00057 template <class Datatype>
00058 Datatype* FreecellSolverBSearch(Datatype* Key, Datatype* Array, int Length,
00059 ACompareNodesAlgorithm<Datatype, void>* Compare, bool* Found)
00060 {
00061 int Low = 0,
00062 High = Length - 1,
00063 Mid,
00064 Result;
00065
00066 while (Low <= High)
00067 {
00068 Mid = ((Low+High)>>1);
00069 Result = Compare->Compare(Key, &Array[Mid], NULL);
00070
00071 if (Result < 0)
00072 {
00073 High = Mid-1;
00074 }
00075 else if (Result > 0)
00076 {
00077 Low = Mid+1;
00078 }
00079 else
00080 {
00081 *Found = true;
00082 return (&Array[Mid]);
00083 }
00084 }
00085
00086 *Found = false;
00087 return (&Array[High+1]);
00088 }
00089
00101 template <class Datatype>
00102 void SFOMergeLargeAndSmallSortedArrays(Datatype* BigArray, int BigArraySize,
00103 Datatype* SmallArray, int SmallArraySize,
00104 ACompareNodesAlgorithm<Datatype, void>* Compare)
00105 {
00106 int NumberOfBigItemsMoved = 0,
00107 Position,
00108 StartOffset,
00109 EndOffset;
00110 Datatype* PositionPtr;
00111 bool Found;
00112
00113 for (int ItemToMove = SmallArraySize-1 ; ItemToMove >= 0; ItemToMove--)
00114 {
00115 PositionPtr = FreecellSolverBSearch<Datatype>(&SmallArray[ItemToMove],
00116 BigArray, BigArraySize-NumberOfBigItemsMoved,
00117 Compare, &Found);
00118
00119 Position = PositionPtr-BigArray;
00120
00121 EndOffset = BigArraySize - NumberOfBigItemsMoved + ItemToMove + 1;
00122 StartOffset = EndOffset + Position - (BigArraySize - NumberOfBigItemsMoved);
00123
00124 memmove(&BigArray[StartOffset], &BigArray[Position], (EndOffset - StartOffset)*sizeof(Datatype));
00125 memcpy(&BigArray[StartOffset-1], &SmallArray[ItemToMove], sizeof(Datatype));
00126 NumberOfBigItemsMoved += (EndOffset - StartOffset);
00127 }
00128 }
00129
00130 #endif