// 全体のプログラム例(発展問題含む)
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#define N 200000
void bubble_sort_array(int a[], int n);//バブルソート
void selection_sort_array(int a[], int n);//選択ソート
void insertion_sort_array(int a[], int n);//挿入ソート
void merge_sort(int array[], int first, int last);
void quick_sort(int ary[], int left, int right);
unsigned long long int k;
int array[N],buff[N];
void main()
{
int i;
int n=N,num=0,count=0,seed; /*table, arrayに登録されているデータの個数*/
int output[N];
clock_t start, end;
scanf("%d",&seed);
srand(seed);
//配列生成
for(i=0;i<n;i++)
{
array[i] = rand()%114514; //ランダムに生成
//hairetus[i] = n - i - 1;で逆順生成
}
k = 0;
start = clock();
selection_sort_array(array, n); //選択ソート
end = clock();
printf("%.6f sec\n",(double)(end-start)/CLOCKS_PER_SEC);
printf("\n step is %llu\n",k);
k = 0;
srand(seed);
//配列生成
for(i=0;i<n;i++)
{
array[i] = rand()%114514; //ランダムに生成
//hairetus[i] = n - i - 1;で逆順生成
}
start = clock();
insertion_sort_array(array, n); //挿入ソート
end = clock();
printf("%.6f sec\n",(double)(end-start)/CLOCKS_PER_SEC);
printf("\n step is %llu\n",k);
srand(seed);
//配列生成
for(i=0;i<n;i++)
{
array[i] = rand()%114514; //ランダムに生成
//hairetus[i] = n - i - 1;で逆順生成
}
start = clock();
quick_sort(array,0, n-1); //QUICKソート
end = clock();
printf("%.6f sec\n",(double)(end-start)/CLOCKS_PER_SEC);
printf("\n step is %llu\n",k);
srand(seed);
//配列生成
for(i=0;i<n;i++)
{
array[i] = rand()%114514; //ランダムに生成
//hairetus[i] = n - i - 1;で逆順生成
}
k = 0;
start = clock();
for(i=0;i<N;i++)
{
insert(array, N - i , count);
count++;
}
num = N;
for(i = 1; i <= N; i++)
{
output[i] = delete_root(array, &num);
}
end = clock();
printf("%.6f sec\n",(double)(end-start)/CLOCKS_PER_SEC);
printf("\n step is %llu\n",k);
k=0;
srand(seed);
//配列生成
for(i=0;i<n;i++)
{
array[i] = rand()%114514; //ランダムに生成
//hairetus[i] = n - i - 1;で逆順生成
}
start = clock();
merge_sort(array,0,N-1);
end = clock();
printf("%.6f sec\n",(double)(end-start)/CLOCKS_PER_SEC);
printf("\n step is %llu\n",k);
}
//バブルソート
void bubble_sort_array(int a[], int n)
{
int i, j, t;
for(i = 0; i < n; i++)
{
for(j = n - 1; j > i; j--)
{
if(a[j] < a[j-1])
{
//交換
t = a[j];
a[j] = a[j-1];
a[j-1] = t;
}
}
}
}
//選択ソート
void selection_sort_array(int a[], int n)
{
int i, j, t, lowest, lowkey;
for(i = 0; i < n - 1; i++)
{
k++;
//lowest:最小値の値 lowkey:最小値の値を格納する要素の添え字
//とりあえず最小値の値をa[i]としておく
lowest = a[i];
k++;
lowkey = i;
k++;
for(j = i + 1; j < n ; j++)
{
k++;
//lowestより低い値を格納する要素が見つかった場合、lowestを更新する
if(lowest > a[j]){
k++;
lowest = a[j];
k++;
lowkey = j;
k++;
}
}
//交換
t = a[i];
k++;
a[i] = a[lowkey];
k++;
a[lowkey] = t;
k++;
}
}
//挿入ソート
void insertion_sort_array(int a[], int n)
{
int i, j, t;
for(i = 1; i < n; i++) //
{
k++;
j = i; //未ソート部分の先頭の添え字
k++;
while(a[j-1] > a[j] && j>0)//未ソート部分の先頭を適切な位置へ挿入
{
k++;
// 交換作業
t = a[j-1];
k++;
a[j-1] = a[j];
k++;
a[j] = t;
k++;
j--;
k++;
}
}
}
void upHeap(int array[], int n)
{
int tmp, size;
size = n;
k++;
while(array[n] < array[n/2] && n != 1)
{
tmp = array[n];
k++;
array[n] = array[n/2];
k++;
array[n/2] = tmp;
k++;
n = n / 2;
k++;
}
}
void downHeap(int array[], int n, int size)
{
int tmp, bigger;
if(2*n > size)
{
k++;
return;
}
else if(2*n + 1 > size || array[2*n] < array[2*n+1])
{
k++;
k++;
bigger = 2*n;
}
else
{
k++;
k++;
bigger = 2*n+1;
}
if(array[n] > array[bigger])
{
k++;
tmp = array[bigger];
k++;
array[bigger] = array[n];
k++;
array[n] = tmp;
k++;
downHeap(array, bigger, size);
k++;
}
else
{
k++;
return;
}
}
int insert(int array[], int x, int count)
{
array[count + 1] = x;
k++;
upHeap(array, count + 1);
k++;
return 1;
}
int delete_root(int array[], int *num)
{
int tmp,ret;
tmp = array[1];
k++;
ret = array[1];
k++;
array[1] = array[*num];
k++;
array[*num] = -1;
k++;
*num = *num - 1;
k++;
downHeap(array, 1, *num);
k++;
return ret;
}
void merge(int a[],int as,int b[],int bs,int c[]){ //併合するだけの関数
int pa=0;//配列aの現在地
int pb=0;//配列bの現在地
int pc=0;//配列cの現在地
while(pa<as && pb<bs){
if(a[pa]<b[pb]){
c[pc]=a[pa];
pc++;
pa++;
}else{
c[pc]=b[pb];
pb++;
pc++;
}
}
while(pa<as){
c[pc]=a[pa];
pc++;
pa++;
}
while(pb<bs){
c[pc]=b[pb];
pc++;
pb++;
}
}
void merge_sort(int array[],int first,int last){
int center=(first+last)/2;
int i,j;
if(first<last){
merge_sort(array,first,center);
merge_sort(array,center+1,last);
for(i=first;i<=last;i++){
buff[i]=array[i];
}
merge(&buff[first],center-first+1,&buff[center+1],last-center,&array[first]);
}
}
void quick_sort(int ary[], int left, int right)
{
int arL, arR, pivot, tmp, l_stack[1000], r_stack[1000], ptr=0;
//値の設定.arLとarRは大小探索に利用する.
arL = left;
arR = right;
l_stack[ptr] = left;
r_stack[ptr] = right;
ptr++;
//pivot決定
while (ptr-- >0) {
arL = left = l_stack[ptr];
arR = right = r_stack[ptr];
pivot = arL;
//探索部分と交換操作
while(arL <= arR)
{
for(arL = arL; ary[arL] < ary[pivot]; arL++)
{}
for(arR = arR; ary[arR] > ary[pivot]; arR--)
{}
if(arL <= arR)
{
tmp = ary[arL];
ary[arL] = ary[arR];
ary[arR] = tmp;
arL++;
arR--;
}
}
if (arR - left < right - arL) {
tmp = left;
left = arL;
arL = tmp;
tmp = right;
right = arR;
arR = tmp;
}
if(left < arR){
l_stack[ptr] = left;
r_stack[ptr] = arR;
ptr++;
}
if(right > arR){
l_stack[ptr] = arL;
r_stack[ptr] = right;
ptr++;
}
}
}