采用面向对象的思想对排序进行封装,即成员变量和实现方法的接口
typedef int DateType;
typedef struct sort
{
DateType *arr;
DateType len;
void (*BubbleSort)(struct sort * sort);
void (*SelectionSort)(struct sort * sort);
void (*InsertSort)(struct sort* sort);
void (*ShellSort)(struct sort* sort);
//add
void (*PrintSort)(struct sort * sort);
} SORT_T;
冒泡排序(英语:Bubble Sort)是一种简单的排序算法。它重复地走访过要排序的数列,一次比较两个元素,如果他们的顺序(如从大到小、首字母从A到Z)错误就把他们交换过来。
冒泡排序算法基本思想实现步骤:
1)对数组中的各数据,依次比较相邻的两个元素的大小。
2)如果前面的数据大于后面的数据,就比较这两个元素。经过第一轮的多次比较排序后,便可把最小的数据排好
3)再用同样的方法把剩下数据逐步比较,最后便可按照从小到大的顺序排好数组中各数据的顺序
void BubbleSort(SORT_T * sort)
{
int i, j;
int temp;
//循环遍历整个数组
for (i = 0; i < sort->len - 1; i++)
{
//从最后的数据开始依次比较
for (j = sort->len - 1; j > i; j--)
{
//如果前面的数据大于后面的数据则调换
if (sort->arr[j - 1] > sort->arr[j])
{
temp = sort->arr[j - 1];
sort->arr[j - 1] = sort->arr[j];
sort->arr[j] = temp ;
}
}
}
}
选择排序(Selection sort)是一种简单直观的排序算法。它的工作原理如下。首先在未排序序列中找到最小(大)元素,存放到排序序列的起始位置,然后,再从剩余未排序元素中继续寻找最小(大)元素,然后放到已排序序列的末尾。以此类推,直到所有元素均排序完毕。
选择排序算法基本思想实现步骤:
1)首先从原始数组中选择一个最小的的数据,将其和位于第一个位置的数据进行交互
2)从剩下的n-1个数据中选择次小的一个元素,将其和位于第2个位置的数据交互
3)这样不断重复,直到最后两个数据完成交换。
4)最后完成对原始数据排序交换
void SelectionSort(SORT_T * sort)
{
int i, j, min;
int tmp;
//循环遍历整个数组
for (i = 0; i < sort->len - 1 ; i++)
{
min = i;//记录最小的下标
for ( j = i + 1; j < sort->len ; j ++ )
{
if (sort->arr[j] < sort->arr[min])
{
min = j;
}
}
if (min != i)
{
tmp = sort->arr[i];
sort->arr[i] = sort->arr[min];
sort->arr[min] = tmp;
}
}
}
插入排序(英语:Insertion Sort)是一种简单直观的排序算法。它的工作原理是通过构建有序序列,对于未排序数据,在已排序序列中从后向前扫描,找到相应位置并插入。插入排序在实现上,通常采用in-place排序(即只需用到 {\displaystyle O(1)} {\displaystyle O(1)}的额外空间的排序),因而在从后向前扫描过程中,需要反复把已排序元素逐步向后挪位,为最新元素提供插入空间。
void InsertSort(SORT_T* sort)
{
int i, j, tmp;
for (i = 1; i < sort->len; i++)
{
tmp = sort->arr[i];//将每次需要插入的元素保存到变量tmp中,
j = i - 1;//变量j表示要插入的位置,将当前位置序号为i的数插入序号i-1(即前一个数的位置)
while (j >= 0 && sort->arr[j] > tmp) //如果序号j元素大于变量tmp(需要插入的元素),则将序号为j的元素向后移,
{
sort->arr[j + 1] = sort->arr[j];
j--;//判断前一个数据是否需要向后移动,通过while找个一个比tmp值小的元素,
}
sort->arr[j + 1] = tmp;//再序号为j的元素进行插入
}
}
希尔排序,也称递减增量排序算法,是插入排序的一种更高效的改进版本。希尔排序是非稳定排序算法。
希尔排序是基于插入排序的以下两点性质而提出改进方法的:
插入排序在对几乎已经排好序的数据操作时,效率高,即可以达到线性排序的效率
但插入排序一般来说是低效的,因为插入排序每次只能将数据移动一位
void ShellSort(SORT_T* sort)
{
int i, j;
int tmp, r;
for (r = sort->len / 2; r >= 1; r = r / 2) //化组排序,将数组分为多个序列
{
for ( i = r; i < sort->len; ++i)//按设置的间距r,分别比较对应的元素
{
tmp = sort->arr[i];
j = i - r;
while (j >= 0 && sort->arr[j] > tmp)
{
sort->arr[j + r] = sort->arr[j];
j = j - r;
}
sort->arr[j + r] = tmp;
}
}
}
/*
* Open Your Mind!
*
* .-~~~~~~~~~-._ _.-~~~~~~~~~-.
* __.' ~. .~ `.__
* .'// \./ \\`.
* .'// | \\`.
* .'// .-~"""""""~~~~-._ | _,-~~~~"""""""~-. \\`.
* .'//.-" `-. | .-' "-.\\`.
* .'//______.============-.. \ | / ..-============.______\\`.
* .'______________________________\|/______________________________`.
*/
void PrintSort(SORT_T * sort)
{
int i;
for (i = 0; i < sort->len; i++)
printf("%d ", sort->arr[i]);
}
void SORT_Init(SORT_T * sort, int *arr, int len)
{
sort->arr = arr;
sort->len = len;
sort->BubbleSort = BubbleSort;
sort->SelectionSort = SelectionSort;
sort->InsertSort = InsertSort;
sort->ShellSort = ShellSort;
sort->PrintSort = PrintSort;
}
int main(int argc, char const *argv[])
{
int arr[] = { 22, 34, 3, 32, 82, 55, 89, 50, 37, 5, 64, 35, 9, 70 };
int len = (int) sizeof(arr) / sizeof(*arr);
SORT_T mysort;
SORT_Init(&mysort, arr, len);
//mysort.BubbleSort(&mysort);
//mysort.SelectionSort(&mysort);
//mysort.InsertSort(&mysort);
mysort.ShellSort(&mysort);
mysort.PrintSort(&mysort);
return 0;
}