清华大学出版社 《数据结构题集(C语言版)》 P169 6.6
#include < stdio.h >
#include < stdlib.h >
#define MAXSIZE 200
int * InitNUM()
{
int * NUM;
NUM = ( int * )malloc( sizeof ( int ) * (MAXSIZE + 1 ));
int i;
for (i = 1 ; i <= MAXSIZE; i ++ )
{
NUM[i] = abs(rand()) % 500 ;
}
return NUM;
}
void PrintNUM( int * NUM)
{
int i;
printf( " \n--------------------------------------------------------------------\n " );
for (i = 1 ; i <= MAXSIZE; i ++ )
{
if (i % 10 == 1 )
printf( " \n " );
printf( " %5d " , NUM[i]);
}
printf( " \n--------------------------------------------------------------------\n " );
}
int * CopyNUM( int * NUM1)
{
int * NUM2;
NUM2 = ( int * )malloc( sizeof ( int ) * (MAXSIZE + 1 ));
int i;
for (i = 0 ; i <= MAXSIZE; i ++ )
{
NUM2[i] = NUM1[i];
}
return NUM2;
}
void QiPao( int * NUM1)
{
int * NUM;
NUM = CopyNUM(NUM1);
printf( " \n====================================================================\n " );
printf( " \n[起泡排序]\n " );
int i, j, temp, movecount, comparecount;
movecount = comparecount = 0 ;
for (i = 1 ; i < MAXSIZE; i ++ )
{
for (j = 1 ; j <= MAXSIZE - i; j ++ )
{
comparecount ++ ;
if (NUM[j] > NUM[j + 1 ])
{
temp = NUM[j];
NUM[j] = NUM[j + 1 ];
NUM[j + 1 ] = temp;
movecount += 3 ;
}
}
}
PrintNUM(NUM);
printf( " \n关键字比较次数:%d 关键字移动次数:%d\n " , comparecount, movecount);
printf( " \n====================================================================\n " );
free(NUM);
}
void ZhiJieChaRu( int * NUM1)
{
int * NUM;
NUM = CopyNUM(NUM1);
printf( " \n====================================================================\n " );
printf( " \n[直接插入排序]\n " );
int i, j, movecount, comparecount;
movecount = comparecount = 0 ;
for (i = 2 ; i <= MAXSIZE; i ++ )
{
comparecount ++ ;
if (NUM[i] < NUM[i - 1 ])
{
movecount += 2 ;
NUM[ 0 ] = NUM[i];
NUM[i] = NUM[i - 1 ];
for (j = i - 2 ; NUM[ 0 ] < NUM[j]; j -- )
{
comparecount ++ ;
movecount ++ ;
NUM[j + 1 ] = NUM[j];
}
NUM[j + 1 ] = NUM[ 0 ];
movecount ++ ;
}
}
PrintNUM(NUM);
printf( " \n关键字比较次数:%d 关键字移动次数:%d\n " , comparecount, movecount);
printf( " \n====================================================================\n " );
free(NUM);
}
int SelectMinNUM( int i, int * NUM)
{
long j, min = 999999 ;
for (; i <= MAXSIZE; i ++ )
{
if (NUM[i] < min)
{
min = NUM[i];
j = i;
}
}
return j;
}
void JianDanXuanZe( int * NUM1)
{
int * NUM;
NUM = CopyNUM(NUM1);
printf( " \n====================================================================\n " );
printf( " \n[简单选择排序]\n " );
int i, j, temp, movecount, comparecount;
movecount = comparecount = 0 ;
for (i = 1 ; i < MAXSIZE; i ++ )
{
j = SelectMinNUM(i, NUM);
comparecount += (MAXSIZE - i + 1 );
if (i != j)
{
temp = NUM[i];
NUM[i] = NUM[j];
NUM[j] = temp;
movecount += 3 ;
}
}
PrintNUM(NUM);
printf( " \n关键字比较次数:%d 关键字移动次数:%d\n " , comparecount, movecount);
printf( " \n====================================================================\n " );
free(NUM);
}
int Partion( int * NUM, int low, int high, int * comparecountp, int * movecountp)
{
int pivotkey;
NUM[ 0 ] = NUM[low];
( * movecountp) ++ ;
pivotkey = NUM[low];
while (low < high)
{
while (low < high && NUM[high] >= pivotkey)
{
( * comparecountp) ++ ;
high -- ;
}
NUM[low] = NUM[high];
( * movecountp) ++ ;
while (low < high && NUM[low] <= pivotkey)
{
( * comparecountp) ++ ;
low ++ ;
}
NUM[high] = NUM[low];
( * movecountp) ++ ;
}
NUM[low] = NUM[ 0 ];
( * movecountp) ++ ;
return low;
}
void QSort( int * NUM, int low, int high, int * comparecountp, int * movecountp)
{
int pivotloc;
if (low < high)
{
pivotloc = Partion(NUM, low, high, comparecountp, movecountp);
QSort(NUM, low, pivotloc - 1 , comparecountp, movecountp);
QSort(NUM, pivotloc + 1 , high, comparecountp, movecountp);
}
}
void KuaiSu( int * NUM1)
{
int comparecount, movecount;
comparecount = movecount = 0 ;
int * NUM;
NUM = CopyNUM(NUM1);
printf( " \n====================================================================\n " );
printf( " \n[快速排序]\n " );
QSort(NUM, 1 , MAXSIZE, & comparecount, & movecount);
PrintNUM(NUM);
printf( " \n关键字比较次数:%d 关键字移动次数:%d\n " , comparecount, movecount);
printf( " \n====================================================================\n " );
free(NUM);
}
void ShellInsert( int * NUM, int dk, int * comparecountp, int * movecountp)
{
int i, j;
for ( i = dk + 1 ; i <= MAXSIZE; i ++ )
{
( * comparecountp) ++ ;
if (NUM[i] < NUM[i - dk])
{
NUM[ 0 ] = NUM[i];
( * movecountp) ++ ;
for (j = i - dk; j > 0 && NUM[ 0 ] < NUM[j]; j -= dk)
{
( * comparecountp) ++ ;
NUM[j + dk] = NUM[j];
( * movecountp) ++ ;
}
NUM[j + dk] = NUM[ 0 ];
( * movecountp) ++ ;
}
}
}
void XiEr( int * NUM1)
{
int * NUM;
NUM = CopyNUM(NUM1);
printf( " \n====================================================================\n " );
printf( " \n[希尔排序]\n " );
int k;
int comparecount, movecount;
comparecount = movecount = 0 ;
for (k = 21 ; k > 0 ; k -= 5 )
{
ShellInsert(NUM, k, & comparecount, & movecount);
}
PrintNUM(NUM);
printf( " \n关键字比较次数:%d 关键字移动次数:%d\n " , comparecount, movecount);
printf( " \n====================================================================\n " );
free(NUM);
}
void HeapAdjust( int * NUM, int s, int m, int * comparecountp, int * movecountp)
{
int j, rc;
rc = NUM[s];
for (j = 2 * s; j <= m; j *= 2 )
{
if (j < m && NUM[j] < NUM[j + 1 ])
{
( * comparecountp) ++ ;
j ++ ;
}
if ( ! (rc < NUM[j]))
{
( * comparecountp) ++ ;
break ;
}
NUM[s] = NUM[j];
( * movecountp) ++ ;
s = j;
}
NUM[s] = rc;
( * movecountp) ++ ;
}
void Dui( int * NUM1)
{
int * NUM;
NUM = CopyNUM(NUM1);
printf( " \n====================================================================\n " );
printf( " \n[堆排序]\n " );
int comparecount, movecount;
comparecount = movecount = 0 ;
int i, temp;
for (i = MAXSIZE / 2 ; i > 0 ; i -- )
HeapAdjust(NUM, i, MAXSIZE, & comparecount, & movecount);
for (i = MAXSIZE; i > 1 ; i -- )
{
temp = NUM[ 1 ];
NUM[ 1 ] = NUM[i];
NUM[i] = temp;
movecount += 3 ;
HeapAdjust(NUM, 1 , i - 1 , & comparecount, & movecount);
}
PrintNUM(NUM);
printf( " \n关键字比较次数:%d 关键字移动次数:%d\n " , comparecount, movecount);
printf( " \n====================================================================\n " );
free(NUM);
}
void main()
{
int * NUM;
NUM = InitNUM();
printf( " \n原数组:\n " );
PrintNUM(NUM);
QiPao(NUM);
ZhiJieChaRu(NUM);
JianDanXuanZe(NUM);
KuaiSu(NUM);
XiEr(NUM);
Dui(NUM);
}