/*
	バブル(bubble)ソート
*/
#include <stdio.h>
#define	DEBUG	1
	int	array[100] = { 18, 2, 11, 7, 19, 17, 16, 5, 13, 10, 20 };
	int	num = 11;
void disp( int n, int buf[] );
void swap( int *x, int *y );
void bsort( int n, int buf[] );
main()
{
	disp( num, array );
	bsort( num, array );
	disp( num, array );
}
/* 配列bufのn個の要素を表示する */
void disp( int n, int buf[] )
{
	int	i;
	for( i = 0; i < n; i++ )
		printf("%3d", buf[i] );
	printf("\n");
}
/* x と y の場所のデータを入れ替える */
void swap( int *x, int *y )
{
	int	t;
	t = *x;
	*x = *y;
	*y = t;
}
/* バブルソートする */
void bsort( int n, int buf[] )
{
	int	i, j;
	for( i = n-1; i >= 1; i-- )
	{
#ifdef	DEBUG
		disp( num, array );	/* この時点の配列データを表示する */
#endif
		for( j = 0; j < i; j++ )
		{
			if( buf[j] > buf[j+1] )
			{
				swap( &buf[j], &buf[j+1] );
			}
		}
	}
}
/* end of bsort0.c */
/*
	直接選択(straight selection)ソート
*/
#include <stdio.h>
#define	DEBUG	1
	int	array[100] = { 18, 2, 11, 7, 19, 17, 16, 5, 13, 10, 20 };
	int	num = 11;
void disp( int n, int buf[] );
void swap( int *x, int *y );
void ssort( int n, int buf[] );
main()
{
	disp( num, array );
	ssort( num, array );
	disp( num, array );
}
/* 配列bufのn個の要素を表示する */
void disp( int n, int buf[] )
{
	int	i;
	for( i = 0; i < n; i++ )
		printf("%3d", buf[i] );
	printf("\n");
}
/* x と y の場所のデータを入れ替える */
void swap( int *x, int *y )
{
	int	t;
	t = *x;
	*x = *y;
	*y = t;
}
/* 選択ソートする */
void ssort( int n, int buf[] )
{
	int	i, j;
	for( i = 0; i < n-1; i++ )
	{
#ifdef	DEBUG
		disp( num, array );	/* この時点の配列データを表示する */
#endif
		for( j = i + 1; j < n; j++ )
		{
			if( buf[i] > buf[j] )
			{
				swap( &buf[i], &buf[j] );
			}
		}
	}
}
/* end of ssort0.c */
/*
	挿入(indertion)ソート
*/
#include <stdio.h>
#define	DEBUG	1
	int	array[100] = { 18, 2, 11, 7, 19, 17, 16, 5, 13, 10, 20 };
	int	num = 11;
void disp( int n, int buf[] );
void isort( int n, int buf[] );
main()
{
	disp( num, array );
	isort( num, array );
	disp( num, array );
}
/* 配列bufのn個の要素を表示する */
void disp( int n, int buf[] )
{
	int	i;
	for( i = 0; i < n; i++ )
		printf("%3d", buf[i] );
	printf("\n");
}
/* 挿入ソートする */
void isort( int n, int buf[] )
{
	int	i, j;
	int	tmp;
	for( i = 1; i < n; i++ )
	{
#ifdef	DEBUG
		disp( num, array );	/* この時点の配列データを表示する */
#endif
		for( tmp = buf[i], j = i; j > 0 && buf[j-1] >= tmp; j-- )
			buf[j] = buf[j-1];
		buf[j] = tmp;
	}
}
/* end of isort.c */
/*
	シェル(shell)ソート
	インターバル数列としては h = 3*h + 1 を採用している
*/
#include <stdio.h>
#define	DEBUG	1
	int	array[100] = { 18, 2, 11, 7, 19, 17, 16, 5, 13, 10, 20 };
	int	num = 11;
void disp( int n, int buf[] );
void shsort( int n, int buf[] );
main()
{
	disp( num, array );
	shsort( num, array );
	disp( num, array );
}
/* 配列bufのn個の要素を表示する */
void disp( int n, int buf[] )
{
	int	i;
	for( i = 0; i < n; i++ )
		printf("%3d", buf[i] );
	printf("\n");
}
/* シェルソートする */
void shsort( int n, int buf[] )
{
	int	i, j, h;
	int	tmp;
	for( h = 1; h <= n/3; h = h*3+1 );
	for( ; h > 0; h = (h-1)/3 )
	{
#ifdef	DEBUG
		printf("h = %d\n", h );
#endif
		for( i = h; i < n; i++ )
		{
#ifdef	DEBUG
			disp( num, array );	/* この時点の配列データを表示する */
#endif
			for( tmp = buf[i], j = i; j > h-1 && buf[j-h] >= tmp; j-=h )
				buf[j] = buf[j-h];
			buf[j] = tmp;
		}
	}
}
/* end of shsort.c */
/*
	クイック(quick)ソート
*/
#include <stdio.h>
#define	DEBUG	1
	int	array[100] = { 18, 2, 11, 7, 19, 17, 16, 5, 13, 10, 20 };
	int	num = 11;
void disp( int n, int buf[] );
void swap( int *x, int *y );
void qsort( int n, int buf[] );
main()
{
	disp( num, array );
	qsort( num, array );
	disp( num, array );
}
/* 配列bufのn個の要素を表示する */
void disp( int n, int buf[] )
{
	int	i;
	for( i = 0; i < n; i++ )
		printf("%3d", buf[i] );
	printf("\n");
}
/* x と y の場所のデータを入れ替える */
void swap( int *x, int *y )
{
	int	t;
	t = *x;
	*x = *y;
	*y = t;
}
/* クイックソートする */
void qsort( int n, int buf[] )
{
void	qsorts( int left, int right, int buf[] );
#ifdef	DEBUG
	int	i;
	for( i = 0; i < 10; i++ )
		printf(" ");
	printf("index ->");
	for( i = 0; i < n; i++ )
		printf("%3d", i );
	printf("\n");
#endif
	qsorts( 0, n-1, buf );
}
void qsorts( int left, int right, int buf[] )
{
	int	i, j;
	int	mid;
	
	mid = buf[(left+right)/2];
#ifdef	DEBUG
	printf("l=%2d, r=%2d, m=%2d: ", left, right, mid );
	disp( num, array );
#endif
	for( i = left, j = right; i <= j; i++, j-- )
	{
		while( buf[i] < mid )
			i++;
		while( buf[j] > mid )
			j--;
		if( i > j )
			break;
		swap( &buf[i], &buf[j] );
	}
	if( left < j )
		qsorts( left, j, buf );
	if( i < right )
		qsorts( i, right, buf );
}
/* end of qsort.c */
/*
	マージ(merge)ソート
*/
#include <stdio.h>
#define	ASIZE	100
#define	DEBUG	1
	int	array[ASIZE] = { 18, 2, 11, 7, 19, 17, 16, 5, 13, 10, 20 };
	int	num = 11;
void disp( int n, int buf[] );
void msort( int n, int buf[] );
main()
{
	disp( num, array );
	msort( num, array );
	disp( num, array );
}
/* 配列bufのn個の要素を表示する */
void disp( int n, int buf[] )
{
	int	i;
	for( i = 0; i < n; i++ )
		printf("%3d", buf[i] );
	printf("\n");
}
/* マージソートする */
void msort( int n, int buf[] )
{
void	msorts( int s, int t, int buf[] );
#ifdef  DEBUG
        int     i;
        for( i = 0; i < 10; i++ )
                printf(" ");
        printf("index ->");
        for( i = 0; i < n; i++ )
                printf("%3d", i );
        printf("\n");
#endif
	msorts( 0, n-1, buf );
}
void	msorts( int s, int t, int buf[] )
{
static	int	tbuf[ASIZE];
	int	i, j, m, k;
	m = (s+t+1)/2;
#ifdef	DEBUG
	printf("s=%2d, m=%2d, t=%2d; ", s, m, t );
	disp( num, array );
#endif
	if( s == t )
		return;
	else
	{
		if( s < m-1 )
			msorts( s, m-1, buf );
		if( m < t )
			msorts( m, t, buf );
	}
	for( k = i = s, j = m; i < m && j <= t; )
	{
		if( buf[i] < buf[j] )
			tbuf[k++] = buf[i++];
		else
			tbuf[k++] = buf[j++];
	}
	while( i < m )
		tbuf[k++] = buf[i++];
	while( j <= t )
		tbuf[k++] = buf[j++];
	for( k = s; k <= t; k++ )
		buf[k] = tbuf[k];
}
/* end of msort.c */
/*
	ヒープ(heap)ソート
*/
#include <stdio.h>
#define	DEBUG	1
	int	array[100] = { 18, 2, 11, 7, 19, 17, 16, 5, 13, 10, 20 };
	int	num = 11;
void disp( int n, int buf[] );
void swap( int *x, int *y );
void hsort( int n, int buf[] );
main()
{
	disp( num, array );
	hsort( num, array );
	disp( num, array );
}
/* 配列bufのn個の要素を表示する */
void disp( int n, int buf[] )
{
	int	i;
	for( i = 0; i < n; i++ )
		printf("%3d", buf[i] );
	printf("\n");
}
/* x と y の場所のデータを入れ替える */
void swap( int *x, int *y )
{
	int	t;
	t = *x;
	*x = *y;
	*y = t;
}
void pause()
{
	char	buf;
	printf("Hit Enter Key:");
	scanf("%c", &buf );
}
/* ヒープソートする */
void hsort( int n, int buf[] )
{
extern	void buildheap(int n, int buf[] );
extern	void heapify(int n, int buf[] );
	int	i;
	buildheap( n, buf );
#ifdef	DEBUG
	pause();
#endif
	for( i = n; i > 1; i-- )
	{
#ifdef	DEBUG
		disp( num, array );
#endif
		swap( &buf[(1)-1], &buf[(i)-1] );
		heapify( i-1, buf );
	}
}
void buildheap( int n, int buf[] )
{
extern	void siftdown( int i, int n, int buf[] );
	int	i, j, k;
#ifdef	DEBUG
	printf("start build\n");
#endif
	for( i = n/2; i >= 1; i-- )
	{
		siftdown( i, n, buf );
#ifdef	DEBUG
		disp( num, array );
#endif
	}
#ifdef	DEBUG
	printf("end of build\n");
#endif
}
void siftdown( int i, int n, int buf[] )
{
	int	j;
	for( ; 2*i <= n; i = j )
	{
		if( 2*i == n )
			j = 2*i;
		else /* 2*i + 1 <= n */
		{	
			if( buf[(2*i+1)-1] > buf[(2*i)-1] )
				j = 2*i + 1;
			else
				j = 2*i;
		}
		if( buf[(j)-1] > buf[(i)-1] )
			swap( &buf[(j)-1], &buf[(i)-1] );
		else
			break;	
	}
}
void heapify( int n, int buf[] )
{
extern	void siftdown( int i, int n, int buf[] );
	siftdown( 1, n, buf );
}
/* end of hsort.c */