提示:
1、读者莫要看到大量的代码就晕头,其实核心的语句就那么几句,详细请看代码说明
2、关于希尔排序相关概念及文字描述,请百度百科
代码说明:
1、为了方便监测调试,直观理解,使用了大量简单的语句确定当前的交换数,看着冗余,读者可以自行修改
2、代码中晦涩的函数与句法并不多,所以没加注释,初学者完全可以边看边百度不懂的函数和句法,有益学习
3、代码中FArray[%d]=%d表示在交换前的操作数状态,同理LArray[%d]=%d表示交换后
4、代码中颜色函数过长,看着冗余,偷了懒,没优化,读者自行修改
5、两个输出函数作用不同
6、在调试结果中,深蓝绿色的数字为此次排序的操作数(限于进入本次i层循环与第一次j循环)
7、代码中跳出j层循环表示跳出或跳过j层循环
调试结果部分截图:
程序实现
//希尔排序
//cpp:定义控制台应用程序的入口点。
//作者Ricardo.M.Tan
#include "stdafx.h"
#include "stdafx.h"
#include <stdlib.h>
#include <iostream>
#include <time.h>
#include <windows.h>
#define MAX 10
void Output(int Array[], int Length){
printf("\t\t");
for (int i = 0; i < Length; ++i){
printf("%d ", Array[i]);
}
printf("\n\n");
}
void Output1(int Array[], int Length, int value1, int value2){
printf("\t\t");
for (int i = 0; i < Length; ++i){
if (Array[i] == value1){
SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE), FOREGROUND_BLUE | FOREGROUND_GREEN);
printf("%d ", Array[i]);
SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE), FOREGROUND_INTENSITY | FOREGROUND_RED);
}
else if (Array[i] == value2){
SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE), FOREGROUND_BLUE | FOREGROUND_GREEN);
printf("%d ", Array[i]);
SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE), FOREGROUND_INTENSITY | FOREGROUND_RED);
}
else{
printf("%d ", Array[i]);
}
}
printf("\n\n");
}
void Ran_Array(int Array[], int Length){
srand((unsigned)time(NULL));
for (int i = 0; i < Length; ++i){
Array[i] = rand() % 100;
if (i >= 1 && Array[i] == Array[i - 1]){
Array[i] = rand() % 100;
}
}
}
void ShellSort(int Array[], int Length){
int step;
int temp1, temp2;
int j, i;
for (step = Length / 2; step > 0; step /= 2)//用来控制步长,最后递减到1
{
printf("--------------\n进入最外层循环\n--------------\n");
//i从第step开始排列,应为插入排序的第一个元素
//可以先不动,从第二个开始排序
for (i = step; i <Length; ++i)
{
printf("--------------\n进入i循环第%d层\n--------------\n", i + 1);
temp1 = Array[i];
temp2 = Array[i - step];
printf("i FArray[%d]=%d \n", i, Array[i]);
for (j = i - step; j >= 0 && temp1 <Array[j]; j -= step)
{
printf("--------------\n进入j循环第%d层\n--------------\n", j + 1);
printf("j FArray[%d]=%d \n", j, Array[j]);
printf("j FArray[%d]=%d \n", j + step, Array[j + step]);
Array[j + step] = Array[j];
printf("j LArray[%d]=%d \n", j, Array[j]);
printf("j LArray[%d]=%d \n", j + step, Array[j + step]);
temp2 = Array[j];
Output(Array, Length);
}
printf("--------------\n跳出j循环\n--------------\n", j);
printf("i LArray[%d]=%d \n", i, Array[i]);
SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE), FOREGROUND_BLUE | FOREGROUND_GREEN);//颜色函数
printf("本次的交换工作在这里完成!\n");
SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE), FOREGROUND_GREEN | FOREGROUND_RED | FOREGROUND_BLUE);
Array[j + step] = temp1;//将第一个位置填上
printf("i LArray[%d]=%d \n", j + step, Array[j + step]);
SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE), FOREGROUND_INTENSITY | FOREGROUND_RED);
Output1(Array, Length, temp1, temp2);
SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE), FOREGROUND_GREEN | FOREGROUND_RED | FOREGROUND_BLUE);
}
printf("--------------\n跳出i循环\n--------------\n", i);
}
printf("--------------\n跳出最外层循环\n--------------\n");
}
int main(){
int Array[MAX];
int Length = sizeof(Array) / sizeof(int);
Ran_Array(Array, Length);
printf("排序前:\n");
Output(Array, Length);
ShellSort(Array, Length);
printf("排序完成\n");
printf("排序后:\n");
Output(Array, Length);
system("pause");
return 0;
}