30/09/2018, 16:30

[Wiki] [Algorithm] tổng hợp một số thuật toán sắp xếp

Gồm có:

merge_sort

random_quick_sort

binary_insert_sort

heap_sort

Cách dùng: tên_hàm(dãy_cần_sắp_xếp,số_phần_tử,kích_thước_1_phần_tử,Hàm_so_sánh);

source code:

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <assert.h>
#include <time.h>

#define __sort
#define type void*
typedef int (*_sort_cmp_fn_t)(const type,const type);

inline type _sort_max(type a,type b,_sort_cmp_fn_t cmp){
	if(cmp(a,b)>0) return a;
	return b;
}
inline type _sort_min(type a,type b,_sort_cmp_fn_t cmp){
	if(cmp(a,b)<0) return a;
	return b;
}
inline void _sort_swap(type a,type b,int size){
	if(size>16){
		type t=malloc(size);
		assert(t!=0);
		memcpy(t,a,size);
		memcpy(a,b,size);
		memcpy(b,t,size);
		free(t);
	}else{
		char tmp[size];
		memcpy(tmp,a,size);
		memcpy(a,b,size);
		memcpy(b,tmp,size);
	}
}

#define A(i) ((a)+(i)*(size))

inline int binary_insert_sort_find(const type x,type a,const int n,
		int size,_sort_cmp_fn_t cmp){
	int l,r,c;
	type cx;
	l=0;
	r=n-1;
	c=r>>1;
	if(cmp(x,A(0))<0){
		return 0;
	}else if(cmp(x,A(r))>0){
		return r;
	}
	cx=A(c);
	while(1){
		const int val=cmp(x,cx);
		if(val<0){
			if(c-l<=1) return c;
			r=c;
		}else{
			if(r-c<=1) return c+1;
			l=c;
		}
		c=l+((r-l)>>1);
		cx=A(c);
	}
}

inline void binary_insert_sort_start(type a,const int start,const int n,
		_sort_cmp_fn_t cmp,int size){
	register int i,j,location;
	type x=malloc(size);
	assert(x!=0);
	for(i=start;i<n;++i){
		if(cmp(A(i-1),A(i))<=0) continue;
		memcpy(x,A(i),size);
		location=binary_insert_sort_find(x,a,i,size,cmp);
		for(j=i-1;j>=location;--j){
			memcpy(A(j+1),A(j),size);
		}
		memcpy(A(location),x,size);
	}
	free(x);
}

inline void binary_insert_sort(type a,const int n, int size,_sort_cmp_fn_t cmp){
	if(n<=1) return;
	binary_insert_sort_start(a,1,n,cmp,size);
}

inline void merge_sort(type a,const int n,int size,_sort_cmp_fn_t cmp){
    if(n<16){
        binary_insert_sort(a,n,size,cmp);
        return;
    }
    int mid=n>>1;
    type newa=malloc(size*n);
    merge_sort(a,mid,size,cmp);
    merge_sort(A(mid),n-mid,size,cmp);
    register int i=0,j=mid,out=0;
    while(out<n){
        if(i<mid){
            if(j<n){
                if(cmp(A(i),A(j))<=0){
                    memcpy(newa+out*size,A(i),size);
                    i++;
                }else{
                    memcpy(newa+out*size,A(j),size);
                    j++;
                }
            }else{
                memcpy(newa+out*size,A(i),size);
                i++;
            }
        }else{
            memcpy(newa+out*size,A(j),size);
            j++;
        }
        out++;
    }
    memcpy(a,newa,size*n);
    free(newa);
}
inline void random_quick_sort_with_range(type a,int size,
		_sort_cmp_fn_t cmp,int p,int q){
	if(q-p<=16){
		binary_insert_sort(A(p),q-p+1,size,cmp);
		return;
	}
	int m=rand()%(q-p+1);
	_sort_swap(A(q),A(p+m),size);
	register int j,r=p-1;
	for(j=p;j<q;j++){
		if(rand()%2){
			if(cmp(A(j),A(q))<=0){
				_sort_swap(A(++r),A(j),size);
			}
		}else{
			if(cmp(A(j),A(q))<0){
				_sort_swap(A(++r),A(j),size);
			}
		}
	}
	_sort_swap(A(++r),A(q),size);
	random_quick_sort_with_range(a,size,cmp,p,r-1);
	random_quick_sort_with_range(a,size,cmp,r+1,q);
}
inline void random_quick_sort(type a,int n,int size,_sort_cmp_fn_t cmp){
	srand(time(NULL));
	random_quick_sort_with_range(a,size,cmp,0,n-1);
}

inline void heap_sift_down(type a,int size,
		_sort_cmp_fn_t cmp,int start,int end){
	register int child,root=start;
	while((root<<1)<=end){
		child=root<<1;
		if(child<end && cmp(A(child),A(child+1))<0){
			child++;
		}
		if(cmp(A(root),A(child))<0){
			_sort_swap(A(root),A(child),size);
			root=child;
		}else return;
	}
}
inline void heapify(type a,int size,_sort_cmp_fn_t cmp,int n){
	register int start=n>>1;
	while(start>=0){
		heap_sift_down(a,size,cmp,start,n-1);
		start--;
	}
}
inline void heap_sort(type a, int n,int size,_sort_cmp_fn_t cmp){
	register int end;
	if(n<2) return;
	end=n-1;
	heapify(a,size,cmp,n);
	while(end>0){
		_sort_swap(A(end),a,size);
		heap_sift_down(a,size,cmp,0,end-1);
		end--;
	}
}
#undef A
#undef type
#undef __sort

int cmplong(const void *a,const void *b){
    return *(long*)a-*(long*)b;
}


int main(){
        long a[]={18,2,2015,1,1,2015};
	int n=6;
	int i;
             random_quick_sort(a,n,sizeof(long),cmplong);
	for(i=0;i<n;++i){
		printf("%ld
",a[i]);
	}
	
	return 0;
}
Bài liên quan
0