清华大学出版社 《数据结构题集(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);
}