/* Shell Sorting. * Implemention history:. * 2013-09-15, Mars Fu, first version. */ /* [Shell Sorting Algorithm]. * Published by Donald L. Shell [CACM 2, 7(July 1959), 30-32]. */ #include "stdafx.h" #include "shellsort.h" #include <math.h> static int get_increment(int s) { int next_hs; next_hs = (1 << s); return next_hs; } int do_shell_sort(void* src, int src_sz, int n, cmp_func cmp, exc_func exchange, dbg_func dbg) { int t; int h; int i,j; float n2; F_S(); if (src == NULL || cmp == NULL || exchange == NULL) return 0; if (src_sz <= 0 || n <= 0) return 0; /* get @t for aux table {h(t),...,h(0)} */ n2 = 2; t = log((double)n) / log((double)n2) + (n%2 ? 1 : -1); /* loop aux table for shell sorting */ while (t >= 0) { h = get_increment(t); /* get h(t) */ /* loop all parts of @src, each part has @h items to be compared. */ for (i = 0; i < n/h; ++i) { /* do the comparison and exchanging for each part. */ for ( j = i+h; j < n; j += h) { if (cmp((char*)src + (j-h)*src_sz, (char*)src + j*src_sz) > 0) { exchange((char*)src + (j-h) * src_sz, (char*)src + j * src_sz); } } } --t; if (dbg != NULL) dbg(src, n, h); } F_E(); return 1; } #ifdef SHELL_SORT_DEBUG static int int_increasing_cmp(void* lv, void* rv) { int tmp_lv, tmp_rv; tmp_lv = *(int*)lv; tmp_rv = *(int*)rv; return (tmp_lv - tmp_rv); } static void exchange_int_item(void* lv, void* rv) { int tmp_lv, tmp_rv; tmp_lv = *(int*)lv; tmp_rv = *(int*)rv; *(int*)lv = *(int*)rv; *(int*)rv = tmp_lv; } static void debug_func(void*src, int n, int h) { int i; debug("%d-sort:\r\n----\r\n", h); for (i = 0; i < n; ++i) { debug("%d ", *((int*)src + i)); } debug("\r\n----\r\n"); } int main(int argc, char* argv[]) { int i; int cnt; const int int_items[] = { 503, 87, 512, 61, 908, 170, 897, 275, 653, 426, 154, 509, 612, 677, 765, 703 }; int ret; debug("[Testing shell sort].. \r\n"); cnt = sizeof(int_items)/sizeof(int_items[0]); debug("src database:\r\n----\r\n"); for (i = 0; i < cnt; ++i) { debug("%d ", int_items[i]); } debug("\r\n----\r\n"); ret = do_shell_sort((void*)int_items, sizeof(int), cnt, int_increasing_cmp, exchange_int_item, debug_func); if (!ret) { debug("failed. \r\n"); goto END; } debug("dst database:\r\n----\r\n"); for (i = 0; i < cnt; ++i) { debug("%d ", int_items[i]); } debug("\r\n----\r\n"); debug("\r\n"); debug("[Testing shell sort].. done. \r\n"); END: while(1); return 0; } #endif /* SHELL_SORT_DEBUG */
#ifndef __SHELLSORT_H__ #define __SHELLSORT_H__ #define SHELL_SORT_DEBUG typedef int(*cmp_func)(void*, void*); typedef void (*exc_func)(void*, void*); typedef void (*dbg_func)(void*, int, int); int do_shell_sort(void* src, int src_sz, int n, cmp_func cmp, exc_func exchange, dbg_func dbg); #endif /* __SHELLSORT_H__ */
#pragma once #include <windows.h> #ifdef _WIN32 #define msleep(x) Sleep(x) #endif #include <stdio.h> #include <tchar.h> #include <stdlib.h> #include <malloc.h> #include <string.h> #include <math.h> #define MY_DEBUG #ifdef MY_DEBUG #define debug printf #else #define debug(x,argc, __VA_ARGS__) ; #endif /* MY_DEBUG */ #define F_S() debug("[%s]..\r\n", __FUNCTION__) #define F_E() debug("[%s]..done. \r\n", __FUNCTION__)
Mars
Sep 15th, 2013