Foundation Sorting: Shellsort

/* 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:
----
", h);
	for (i = 0; i < n; ++i) {
		debug("%d ", *((int*)src + i));
	}
	debug("
----
");
}

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].. 
");

	cnt = sizeof(int_items)/sizeof(int_items[0]);

	debug("src database:
----
");
	for (i = 0; i < cnt; ++i) {
		debug("%d ", int_items[i]);
	}
	debug("
----
");


	ret = do_shell_sort((void*)int_items, sizeof(int), cnt, 
		                 int_increasing_cmp, exchange_int_item, debug_func);
	if (!ret) {
		debug("failed. 
");
		goto END;
	}

	debug("dst database:
----
");
	for (i = 0; i < cnt; ++i) {
		debug("%d ", int_items[i]);
	}
	debug("
----
");

	debug("
");

	debug("[Testing shell sort].. done. 
");

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]..
", __FUNCTION__)
#define F_E() debug("[%s]..done. 
", __FUNCTION__)


Mars

Sep 15th, 2013

原文地址:https://www.cnblogs.com/suncoolcat/p/3325156.html