希尔排序的C语言实现(2)
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
#include <stdio.h>
#include <stdlib.h>
void ShellSort(int a[],int Index);
void PrintArray(const char* strMsg,int array[],int nLength);
int main(int argc, char *argv[])
{
int data[13]={8,5,4,6,13,7,1,9,12,11,3,10,2};
ShellSort(data,13);
//PrintArray("Shell Sort:",data,13);
system("PAUSE");
return 0;
}
/* 希尔排序的思路:
需要三层循环,
第一层循环用于控制步长的变化,步长每缩减一次就进行一轮排序;
第二层循环用于控制按照步长所分割成的各个集合;
第三层循环用于针对单个集合进行插入排序;
注:通过画图观察步长与小组个数的关系,可以知道,对于有13个元素的数组,
当步长为8时,可把数组分为8个小组,其中5组有2个元素,3组只有1个元素
当步长为7时,可把数组分为7个小组,其中1组有1个元素,6组有2个元素
当步长为6时,可把数组分为6个小组,其中1组有3个元素,5组有2个元素
当步长为5时,可把数组分为5个小组,其中3组有3个元素,2组有2个元素
当步长为4时,可把数组分为4个小组,其中1组有4个元素,3组有3个元素
*/
void ShellSort(int a[],int Index) {
int i, j, k; // 循环计数变量
int Temp; // 暂存变量
int Change; // 数据是否改变
int DataStep; // 集合分割的步长
int Pointer; // 进行处理的位置
DataStep = (int) Index / 2; // 初始集合间隔长度
while (DataStep != 0) // 数列仍可进行分割
{
printf("========================\n");
// 对各个集合进行处理
/*(在j自增至DataStep的2倍之前,j代表各小组的第二个元素的位置;
j增至DataStep的3倍之前,j代表各小组的第三个元素的位置;依次类推。
若j-DataStep<0说明j已经是本小组的第一个元素了。)*/
for (j = DataStep; j < Index; j++) {
Change = 0;
Temp = a[j]; //保存当前集合的待排序元素到临时变量
#include <stdlib.h>
void ShellSort(int a[],int Index);
void PrintArray(const char* strMsg,int array[],int nLength);
int main(int argc, char *argv[])
{
int data[13]={8,5,4,6,13,7,1,9,12,11,3,10,2};
ShellSort(data,13);
//PrintArray("Shell Sort:",data,13);
system("PAUSE");
return 0;
}
/* 希尔排序的思路:
需要三层循环,
第一层循环用于控制步长的变化,步长每缩减一次就进行一轮排序;
第二层循环用于控制按照步长所分割成的各个集合;
第三层循环用于针对单个集合进行插入排序;
注:通过画图观察步长与小组个数的关系,可以知道,对于有13个元素的数组,
当步长为8时,可把数组分为8个小组,其中5组有2个元素,3组只有1个元素
当步长为7时,可把数组分为7个小组,其中1组有1个元素,6组有2个元素
当步长为6时,可把数组分为6个小组,其中1组有3个元素,5组有2个元素
当步长为5时,可把数组分为5个小组,其中3组有3个元素,2组有2个元素
当步长为4时,可把数组分为4个小组,其中1组有4个元素,3组有3个元素
*/
void ShellSort(int a[],int Index) {
int i, j, k; // 循环计数变量
int Temp; // 暂存变量
int Change; // 数据是否改变
int DataStep; // 集合分割的步长
int Pointer; // 进行处理的位置
DataStep = (int) Index / 2; // 初始集合间隔长度
while (DataStep != 0) // 数列仍可进行分割
{
printf("========================\n");
// 对各个集合进行处理
/*(在j自增至DataStep的2倍之前,j代表各小组的第二个元素的位置;
j增至DataStep的3倍之前,j代表各小组的第三个元素的位置;依次类推。
若j-DataStep<0说明j已经是本小组的第一个元素了。)*/
for (j = DataStep; j < Index; j++) {
Change = 0;
Temp = a[j]; //保存当前集合的待排序元素到临时变量
//(推算本元素的前一个元素的位置)
Pointer = j - DataStep; //计算当前集合已排序元素列表的最后一个元素的位置
k=0;
// 进行集合内数值的插入排序(边比较边向后移位)
while (Temp < a[Pointer] && Pointer >= 0 && Pointer <= Index) {
printf("当前交换元素:%d(a[%d])-%d(a[%d])\n",a[Pointer],Pointer,a[Pointer + DataStep],Pointer + DataStep);
//将比待排序元素大的已排序元素后移
a[Pointer + DataStep] = a[Pointer];
PrintArray("本次交换结果: ",a,Index);
//计算下一个要比较的已排序元素的位置
Pointer = Pointer - DataStep;
Change = 1;
k++;
}
printf("本集合步长为%d,交换次数为%d\n",DataStep,k);
// (将待排序元素插入到最后的空位上)
a[Pointer + DataStep] = Temp;
if (Change) {
// 打印目前排序结果
PrintArray("本轮排序结果: ",a,Index);
}
printf("------------------------\n");
}
DataStep = DataStep / 2; // 计算下次分割的间隔长度
}
}
void PrintArray(const char* strMsg,int array[],int nLength)
{
int i;
printf("%s",strMsg);
for(i=0;i<nLength;i++)
{
printf("%d ",array[i]);
}
printf("\n");
}
Pointer = j - DataStep; //计算当前集合已排序元素列表的最后一个元素的位置
k=0;
// 进行集合内数值的插入排序(边比较边向后移位)
while (Temp < a[Pointer] && Pointer >= 0 && Pointer <= Index) {
printf("当前交换元素:%d(a[%d])-%d(a[%d])\n",a[Pointer],Pointer,a[Pointer + DataStep],Pointer + DataStep);
//将比待排序元素大的已排序元素后移
a[Pointer + DataStep] = a[Pointer];
PrintArray("本次交换结果: ",a,Index);
//计算下一个要比较的已排序元素的位置
Pointer = Pointer - DataStep;
Change = 1;
k++;
}
printf("本集合步长为%d,交换次数为%d\n",DataStep,k);
// (将待排序元素插入到最后的空位上)
a[Pointer + DataStep] = Temp;
if (Change) {
// 打印目前排序结果
PrintArray("本轮排序结果: ",a,Index);
}
printf("------------------------\n");
}
DataStep = DataStep / 2; // 计算下次分割的间隔长度
}
}
void PrintArray(const char* strMsg,int array[],int nLength)
{
int i;
printf("%s",strMsg);
for(i=0;i<nLength;i++)
{
printf("%d ",array[i]);
}
printf("\n");
}
posted on 2010-08-19 17:02 LeeXiaoLiang 阅读(577) 评论(0) 编辑 收藏 举报