一、             导论

1.         【算法】:算法是完成特定任务的有限指令集。所有的算法必须满足下面的标准:

1)         输入。由外部提供零个或多个输入量。

2)         输出。直到产生一个输出量。

3)         明确性。每条指令必须清楚,不具模糊性。

4)         有限性。如果跟踪算法的指令,那么对于所有的情况,算法经过有限步以后终止。

5)         有效性。每条指令必须非常基础,原则上使用笔和纸就可以实现。

2.         【复杂度】:算法的空间复杂度是其运行所需的存储空间。算法的时间复杂度是其运行所需的计算时间。

 

二、             分治算法

1.         给定一个有n个输入的函数,分治策略建议将输入分为k个不同的子集,1<k<=n,从而产生k个子问题。

2.         二叉查找

int BinSrh ( Type a[] ,int i ,int l ,Type x )

{

         if ( l ==1 ){

if ( x ==a[i] )  return i

else      return 0;

};

else {

         int mid = ( i + 1 ) / 2;

         if ( x == a[mid] )         return mid;

         else if ( x < a[mid] )  return BinSrch ( a ,I ,mid - l ,x );

}

         }

3.         非递归二叉查找

int BinSearch ( Type a[] ,int n ,Type x )

{

         int low = 1 ,high=n;

         while ( low <= high ){

                   int mid = ( low + high ) / 2;

                   if ( x < a[mid] )  high = mid – 1;

                   else if ( x > a[mid])   low = mid + 1;

                   else return ( mid );

         }

         return ( 0 );

}

4.         查找最大值和最小值

void StraightMaxMin ( Type a[] ,int n ,Tyep& max , ,Tyep& min )

{

         max = min = a[1];

         for ( int I = 2 ;I < n ; i++ ){

                   if ( a[i] > max )  max = a[i];

                   if ( a[i] <min )    min = a[i];

         }

}

这种算法在最好,平均和最坏情况下,函数StraightMaxMin都要做2(n-1)次元素比较。

                   if( a[i] > max )   max = a[i];

                   else if ( a[i] < min ) min = a[i];

现在,最好的比较次数为n-1,最坏比较次数为2(n-1)

5.         查找最大值和最小值(递归)

void MaxMin ( int I ,int j ,Type& max , ,Tyep& min )

{

         if ( I == j )  max = min = a[i];

         else if ( I == j-1 ){

                            if ( a[i] < a[j] )    { max = a[j]; min = a[i];}

                            else  { max = a[i]; min = a[j];}

                   }

         else{

                   int mid = ( I + j ) / 2;

                   Type max1 ,min1;

                   MaxMin ( I ,mid ,max ,min )

MaxMin ( mid + 1 ,j ,max1 ,min1 )

if ( max < max1 ) max = max1;

if ( min > min1 ) min = min1;

         }

}

计算机算法现在递推关系为:                            T([n/2]) + T([n/2]) + 2        n>2

                                     T(n)=                  1                   n=2

                                                                 0                                            n=1

n2的幂时,3n/2-2是最好,平均和最坏情况下的比较次数。

6.         归并排序

void MergeSort ( int low ,int high )

{

         if ( low < high ){

                   int mid = ( low + high ) / 2;

                   MergeSort ( low ,mid );

                   MergeSort ( mid+1 ,high );

                   Merge ( low ,mid ,high );

         }

}

void Merge ( int low ,int mid ,int high )

{

         int h = low ,i = low ,j = mid + 1 ,k;

         while ( ( h <= mid ) && ( j <= high ) ){

                   if ( a[h] <= a[j] )         { b[i] = a[h]; h++;}

                   else { b[i] = a[j]; j++;}

         }

         if ( h > mid )      for ( k = j ;k < high ;k++ ){

                                               b[i] = a[k];

                                               i++;

                                     }

         else  for( k = h ;k <= mid ;k++ ){

                            b[i] = a[k];

                            i++;

                   }

         for ( k = low ;k <= high ;k++ )    a[k] = b[k];

}

计算机算法现在递推关系为:                            a                                   n=1,a为常数

                               T(n)= 

                                                                 2T(n/2)+cn                n>1,c为常数

n2的幂时,T(n) = O(n logn)

7.         归并排序(链表)

1)         插入排序

void InsertionSort ( Type a[] ,int n )

{

         for ( int j = 2 ;j<=n ;j++ ){

                   Type item = a[j]; int i = j – 1;

                   while ( ( I >= 1 ) && ( item < a[i] ) ){

                            a[i+1] = a[i]; i--;

                   }

                   a[i+1]=item;

         }

}

2)         使用链的归并排序

int MergeSort1 ( int low ,int high )

{

         if ( ( high – low + 1 ) < 16 )

                   return InsertionSort1 ( a ,link ,low ,high );

         else {

                   int mid = ( low + high ) / 2;

                   int q = MergeSort1 ( low ,mid );

                   int r = MergeSort1 ( mid + 1 ,high );

                   return ( Mege1 ( q ,r ) );

         }

}

3)         归并有序元素的链表

int Mege1 ( int q ,int r )

{

         int I = q ,j = r ,k = 0;

         while ( I && j ) {

                   if ( a[i] <= a[j] ) {

                            link[k] = i; k = i; i = link[i];

                   }

                   else {

                            link[k] = j; k = j; j = link[j];

                   }

         }

         if ( !i ) link[k] = j;

         else link[k] = i;

         return ( link[0] );

}

8.         快速排序

int Partiton ( Type a[] ,int m ,int p )

{

         Type v = a[m]; int I = m ,j = p;

         do{

                   do i++;

                   while ( a[i] < v );

                   do j--;

                   while ( a[j] > v );

                   if ( I < j )    Interchange ( a ,I ,j );

         }while ( I < j );

         a[m] = a[j]; a[j] = v; return ( j );

}

inline void Interchange ( Type a[] ,int i ,int j )

{

         Type p = a[i];

         a[i] = a[j]; a[j] = p;

}

void QuickSort ( int p ,int q )                                                            //递归

{

         if( p < q ){

                   int j = Partition ( a ,p ,q+1 );

                   QuickSort ( p ,j - 1 );

                   QuickSort ( j + 1 ,q );

}

}

void QuickSort2( int p ,int q )                                                           //迭代

{

         Stack<int> stack( SIZE )                                                          //SIZE is 2 * log(n)

         do{

                   while ( p < q ){

                            int j = Partition ( a ,p ,q + 1 );

                            if ( ( j - p ) < ( q - j ) ){

                                     stack.Add ( j + 1 );

                                     stack.Add ( q );

                                     q = j -1;

                            }

                            else{

                                     stack.Add ( p );

                                     stack.Add ( j - 1 );

                                     p = j + 1;

                            }

                   }

         if ( stack.stackEmpty() )   return;

         stack.Delect ( q );

         stack.Delect ( p );

         }while ( 1 );

}

9.         随机快速排序算法

void RQuickSort ( int p ,int q )

{

         if ( p < q ){

                   if ( ( q - p ) > 5 ) Interchange ( a ,random() % ( q – p + 1 ) + p ,p );

int j = Partition ( a ,p ,q + 1 ;

                   RQuickSort ( p ,j - 1 );

                   RQuickSort ( j + 1 ,q );

         }

}

10.     查找第k最小元素

void Select1 ( Type a[] ,int n ,int k )

{

         int low = 1 ,up = n + 1;

         a [n+1] = INFTY;                                             //a[n+1] is set to infinity

         do{

                   int j = Partition ( a ,low ,up );

                   if ( k == j ) return;

                   else if ( k < j )    up = j;

                   else low = j + 1;

         }while (1);

}

 

void Select2 ( Type a[] ,int k ,int low ,int up )

{

         do{

                   int n = up – low +1;

                   if ( n <= r ){

                            InsertionSort ( a ,low ,up );

                            return ( low + k -1 );

                   }

                   for ( int I = 1 ;I <= ( n / r ) ; i++ ){

                            InsertionSort ( a ,low + ( i - 1 ) * r ,low + i * r -1);

                            Interchange ( a ,low + I -1 , low + ( I - 1 ) * r + Ceil ( r ,2 ) - 1 );

                   }

                   int j = Select2 ( a ,Ceil ( n / r ,2 ) ,low ,low + ( n / r ) - 1 );

                   Interchange ( a ,low ,j );

                   j = Partition ( a ,low ,up + 1 );

                   if ( k == ( j – low + 1 ) )       return (j);

                   else if ( k < ( j – low + 1 ) )          up = j – 1;

                   else { k -= ( j – low + 1 ); low = j + 1;}

         }while(1);

}

int Ceil ( int a ,int b )

{

         if ( ( a % b ) == 0 )      reutn ( a/b );

         else return ( (a/b) + 1 );

}

11.     Graham扫描算法(如果S为平面中的点的集合,Graham扫描算法从S中找出有最小的y坐标的点p(通过选出最左边的点打破平局)。然后根据点和p连线与正x轴所称的角度讲S中的点排序。)

#define NIL  0

#include <iostream.h>

struct point {
                   float x ,y;

         struct point *prev ,*next;

};

typedef struct point Type;

class PointSet

{

         private:

                   Type* ptslist;

                   float Area ( float ,float ,float ,float ,float ,float );

                   void PrintList ( Type * );

                   void Scan ( Type * );

                            coid Sort ( Type * );

                   public:

                            PointSet() {ptslist = NIL; }

                            void Insert ( float a ,float b );

                            void ConvexHull ( );

         };

         void PointSet :: Scan ( Type* list)

         {

                   Type *p = list, *p1 = list, *p2, *p3;

                   float temp;

                   do{

                            p2 = p1->next;

                            if ( p2->next )   p3 = p2->next;

                            else p3 = p;

                            temp = Area ( p1->x ,p1->y ,p2->x ,p2->y ,p3->x ,p3->y );

                            if ( temp >= 0.0 )       p1 = p1->next;

                            else{

                                     p1->next = p3;

                                     p3->prev = p1;

                                     delete p2;

                                     p1 = p1->prev;

                            }

                   }while ( !( ( p3 == p ) && ( temp >= 0.0 ) ) );

}

void PointSet :: ConvexHull( )

{

         Sort ( ptslist );

         Scan ( ptslist );

         PrintList ( ptslist );

}

 

三、贪心算法(待续……)