您的位置:首页 > 编程语言 > C语言/C++

算法第四版 排序算法的C语言实现

2017-10-14 22:54 316 查看
//alsg4.h
#ifndef ALSG4_H__
#define ALSG4_H__
#include <stdio.h>
#include <stdlib.h>
#include <sys/time.h>
#include <time.h>
typedef unsigned char byte;
typedef char* String;
typedef struct int_array {
int *arr;
int length;
}IntArray;

extern unsigned long NumberOfless;
extern unsigned long NumberOfexch;

int isEmpty(void);
int readInt(void);
double readDouble(void);
float readFloat(void);
long readLong(void);
char readChar(void);
byte readByte(void);
String readString(void);
/**
*   读取输入
*/
IntArray readInts(void);
void Free(IntArray);
double* readDoubles(String name);
String* readStrings(String name);
/**
*   排序算法 实现在sort.c中
*/
void Selection(IntArray);   //选择排序
void Insertion(IntArray);   //插入排序
void Shell(IntArray);       //希尔排序

void Quick(IntArray a);
void quick_sort(int *, int, int);
int partition(int *, int, int);

void MergeBU(IntArray a);
void Merge(IntArray);
void merge(int *, int, int, int, int *);
void merge_sort(int *,int , int, int *);
//排序算法公共函数
int less(int , int );       //比较函数
void exch(int *,int ,int);  //交换函数
int isSorted(IntArray a);

IntArray IntArrayCopy(IntArray);

IntArray RandomIntArray(int,int,int);
IntArray OrderIntArray(int);
IntArray ReverseOrderIntArray(int);

#endif


//algs4.c
#include "algs4.h"

int readInt(void) {
int n;
scanf("%d",&n);
return n;
}
IntArray readInts(void) {
IntArray a = {NULL,0};
int n;
a.arr=(int*)calloc(a.length,sizeof(int));
while(scanf("%d",&n)!=EOF)
{
a.arr = (int *)realloc(a.arr,(++a.length)*sizeof(int));
*(a.arr + a.length - 1) = n;
}
return a;
}
IntArray IntArrayCopy(IntArray a) {
IntArray b;
b.length = a.length;
b.arr =(int*)calloc(b.length,sizeof(int));
for(int i = 0;i < a.length; i++)    b.arr[i] = a.arr[i];
return b;
}

void Free(IntArray a) {
free(a.arr);
}

IntArray RandomIntArray(int min,int max,int size) {
IntArray a;
a.length = size;
a.arr=(int*)calloc(a.length,sizeof(int));
srand((unsigned)time(NULL));
for(int i = 0;i < a.length; i++)    a.arr[i] = rand()%(max-min+1)+min;
return a;
}
IntArray OrderIntArray(int size) {
IntArray a;
a.length = siz
4000
e;
a.arr=(int*)calloc(a.length,sizeof(int));
for(int i = 0;i < a.length; i++)    a.arr[i] = i;
return a;
}
IntArray ReverseOrderIntArray(int size) {
IntArray a;
a.length = size;
a.arr=(int*)calloc(a.length,sizeof(int));
srand((unsigned)time(NULL));
for(int i = 0;i < a.length; i++)    a.arr[i] = a.length - i - 1;
return a;
}


//sort.c
#include "algs4.h"

unsigned long NumberOfless = 0;
unsigned long NumberOfexch = 0;

//选择排序
void Selection(IntArray a)
{
NumberOfless = 0;
NumberOfexch = 0;

struct  timeval  start;
struct  timeval  end;
unsigned long timer;
gettimeofday(&start,NULL);

for(int i = 0; i < a.length; i++)
{
int min = i;
for(int j = i+1; j < a.length; j++)
if(less(a.arr[j], a.arr[min])) min = j;
exch(a.arr, i, min);
}

gettimeofday(&end,NULL);
timer = 1000000 * (end.tv_sec-start.tv_sec)+ end.tv_usec-start.tv_usec;
printf("Selection:ArraySize=%-10d NumberOfLess=%-10ld NumberOfExch=%-10ld SumLessExch=%-10ld timer=%ld us.\n",
a.length,NumberOfless,NumberOfexch,NumberOfless+NumberOfexch,timer);
}
//插入排序
void Insertion(IntArray a)
{
NumberOfless = 0;
NumberOfexch = 0;

struct  timeval  start;
struct  timeval  end;
unsigned long timer;
gettimeofday(&start,NULL);

for (int i = 1; i < a.length; i++)
{
for(int j = i; j > 0 && less(a.arr[j], a.arr[j-1]); j--)
exch(a.arr, j, j-1);
}
gettimeofday(&end,NULL);
timer = 1000000 * (end.tv_sec-start.tv_sec)+ end.tv_usec-start.tv_usec;
printf("Insertion:ArraySize=%-10d NumberOfLess=%-10ld NumberOfExch=%-10ld SumLessExch=%-10ld timer=%ld us.\n",
a.length,NumberOfless,NumberOfexch,NumberOfless+NumberOfexch,timer);
}
//希尔排序
void Shell(IntArray a)
{
NumberOfless = 0;
NumberOfexch = 0;

struct  timeval  start;
struct  timeval  end;
unsigned long timer;
gettimeofday(&start,NULL);

int N = a.length;
int h = 1;
while(h < N/3) h = 3*h + 1; //1, 4, 13, 40, 121, 364, 1093, ...
while(h>=1)
{   //将数组变为h有序
for (int i = h; i < N; i++)
{
for (int j = i; j >=h && less(a.arr[j], a.arr[j-h]);j -= h)
exch(a.arr ,j ,j-h);
}
h = h/3;
}
gettimeofday(&end,NULL);
timer = 1000000 * (end.tv_sec-start.tv_sec)+ end.tv_usec-start.tv_usec;
printf("Shell    :ArraySize=%-10d NumberOfLess=%-10ld NumberOfExch=%-10ld SumLessExch=%-10ld timer=%ld us.\n",
a.length,NumberOfless,NumberOfexch,NumberOfless+NumberOfexch,timer);
}
//归并排序
void Quick(IntArray a)
{
NumberOfless = 0;
NumberOfexch = 0;

struct  timeval  start;
struct  timeval  end;
unsigned long timer;
gettimeofday(&start,NULL);

quick_sort(a.arr,0,a.length - 1);

gettimeofday(&end,NULL);
timer = 1000000 * (end.tv_sec-start.tv_sec)+ end.tv_usec-start.tv_usec;
printf("Quick    :ArraySize=%-10d NumberOfLess=%-10ld NumberOfExch=%-10ld SumLessExch=%-10ld timer=%ld us.\n",
a.length,NumberOfless,NumberOfexch,NumberOfless+NumberOfexch,timer);

}
void Merge(IntArray a)
{
NumberOfless = 0;
NumberOfexch = 0;

struct  timeval  start;
struct  timeval  end;
unsigned long timer;
gettimeofday(&start,NULL);

IntArray aux;
aux.length = a.length;
aux.arr=(int*)calloc(aux.length,sizeof(int));

merge_sort(a.arr, 0, a.length - 1,aux.arr);

free(aux.arr);

gettimeofday(&end,NULL);
timer = 1000000 * (end.tv_sec-start.tv_sec)+ end.tv_usec-start.tv_usec;
printf("Merge    :ArraySize=%-10d NumberOfLess=%-10ld NumberOfExch=%-10ld SumLessExch=%-10ld timer=%ld us.\n",
a.length,NumberOfless,NumberOfexch,NumberOfless+NumberOfexch,timer);
}

void MergeBU(IntArray a)
{
NumberOfless = 0;
NumberOfexch = 0;

struct  timeval  start;
struct  timeval  end;
unsigned long timer;
gettimeofday(&start,NULL);

int N = a.length;
IntArray aux;
aux.length = a.length;
aux.arr=(int*)calloc(aux.length,sizeof(int));
for(int sz = 1; sz < N; sz = sz + sz)
for(int lo = 0; lo < N-sz; lo += sz+sz)
merge(a.arr, lo, lo+sz-1, (lo+sz+sz-1)<(N-1)?(lo+sz+sz-1):(N-1),aux.arr);
free(aux.arr);

gettimeofday(&end,NULL);
timer = 1000000 * (end.tv_sec-start.tv_sec)+ end.tv_usec-start.tv_usec;
printf("MergeBU  :ArraySize=%-10d NumberOfLess=%-10ld NumberOfExch=%-10ld SumLessExch=%-10ld timer=%ld us.\n",
a.length,NumberOfless,NumberOfexch,NumberOfless+NumberOfexch,timer);
}

int less(int v, int w)
{
NumberOfless++;
if(v < w)
return 1;
else
return 0;

}
void exch(int *a,int i,int j)
{
NumberOfexch++;
int t = a[i]; a[i] = a[j]; a[j] = t;
}
int isSorted(IntArray a) {
for (int i = 0; i < a.length; i++)
if (a.arr[i] < a.arr[i-1]) return 0;
return 1;
}

void merge_sort(int *a,int lo, int hi,int *aux)
{
if(hi <= lo) return;
int mid = lo + (hi - lo)/2;
merge_sort(a, lo, mid, aux);
merge_sort(a, mid+1, hi, aux);
merge(a, lo, mid, hi, aux);
}

void merge(int *a, int lo, int mid, int hi, int *aux)
{
int i = lo, j = mid+1;
for(int k = lo; k <= hi; k++)
aux[k] = a[k];
for(int k = lo; k <= hi; k++)
if      (i > mid)               a[k] = aux[j++];
else if (j > hi)                a[k] = aux[i++];
else if (less(aux[j], aux[i]))  a[k] = aux[j++];
else                            a[k] = aux[i++];

}

void quick_sort(int *a, int lo, int hi)
{
if(hi <= lo) return;
int j = partition(a, lo,hi);
quick_sort(a, lo, j-1);
quick_sort(a, j+1, hi);
}
int partition(int *a,int lo,int hi)
{
int i = lo, j = hi+1;
int v = a[lo];
while(1)
{
while(less(a[++i],v)) if(i == hi) break;
while(less(v,a[--j])) if(j == lo) break;
if(i >= j) break;
exch(a, i, j);
}
exch(a, lo, j);
return j;
}


//test.c
#include "algs4.h"
int main() {
//  IntArray a = readInts();
IntArray a = RandomIntArray(0,10000,10000);
//  IntArray a = OrderIntArray(10000);
//  IntArray a = ReverseOrderIntArray(10000);

IntArray ShellA,SelectionA,InsertionA,QuickA,MergeA,MergeBUA;
ShellA = IntArrayCopy(a);
SelectionA = IntArrayCopy(a);
InsertionA = IntArrayCopy(a);
QuickA = IntArrayCopy(a);
MergeA = IntArrayCopy(a);
MergeBUA = IntArrayCopy(a);

Selection(SelectionA);
Insertion(InsertionA);
Shell(ShellA);
Quick(QuickA);
Merge(MergeA);
MergeBU(MergeBUA);

if(!isSorted(SelectionA)) printf("SelectionA Error 数组是无序的\n");
if(!isSorted(InsertionA)) printf("InsertionA Error 数组是无序的\n");
if(!isSorted(ShellA)) printf("ShellA Error 数组是无序的\n");
if(!isSorted(QuickA)) printf("QuickA Error 数组是无序的\n");
if(!isSorted(MergeA)) printf("MergeA Error 数组是无序的\n");
if(!isSorted(MergeBUA)) printf("MergeBUA Error 数组是无序的\n");

Free(a);
Free(ShellA);
Free(SelectionA);
Free(InsertionA);
Free(QuickA);
Free(MergeA);
Free(MergeBUA);

return 1;
}


编译:gcc test.c sort.c algs4.c

运行:./a.out

内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息