其实以上算法的原理都很简单。在本科阶段,我们对这几个算法的基本原理都应该十分熟悉,但对于我,真正落实到是实现这几算法,之前几乎没有试过。现在刚上研一,算法课的第一次作业中,要求我们将这几个算法实现,对这几个算法,在输入规模不同的情况下,比较其实际工作效率。
由于自己对算法具体的实现动手能力存在问题,就这几个算法的具体实现都花了我将近两天的时间。下面是源码:
这是定义的头文件:”h1.h”
#ifndef H1_H
#define H1_H
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
#include <time.h>
#include <process.h>
#include <malloc.h>
#define SCALE 10000000
struct stackNode{ //快排非递归算法需要使用的栈节点
int low;
int high;
};
struct timeNode{ //时间节点
long start;
long end;
};
void quickSortRecursive(int a[], int n);
void qSort(int a[], int low, int high);
int partition(int a[], int low, int high); //以上三个函数是快排递归算法函数
void quickSortNoneRecursive(int a[], int n);//快排非递归算法函数
void mergeSortRecursive( int a[], int n);
void mSort(int a[], int low, int high);
void merge(int a[], int low, int center, int high);//归并排序递归算法函数预定义
void mergeSortNoneRecursive(int a[], int n);//归并排序非递归算法函数预定义
int randomNumber(int i, int j); //用于快排改进算法在low和high之间产生随机数
void swap(int a[], int i, int j); //用于交换数组a中第i+1个和j+1个数
int modifiedPartition(int a[], int low, int high);//改进的partion函数
void modifiedQuickSortRecursive(int a[], int n);
void modifiedQSort(int a[], int low, int high);//改进的快排递归算法函数预定义
void modifiedQuickSortNoneRecursive(int a[], int n); //改进的快排非递归算法函数预定义
#endif
这里是这六个算法的具体实现文件: “sortAlgorithms.c”
#include "h1.h"
int partition(int a[], int low, int high){
int temp = a[low];
while(low < high){
while(low<high && a[high]>=temp){
high--;
}
a[low] = a[high];
while(low<high && a[low]<=temp){
low++;
}
a[high] = a[low];
}
a[low] = temp;
return low;
}
void qSort(int a[], int low, int high){
if( low < high){
int pivotkey = partition( a, low, high );
qSort( a, low, pivotkey-1 );
qSort( a, pivotkey+1, high);
}
}
void quickSortRecursive( int a[], int n){
qSort( a, 0, n-1);
}
//快排递归算法
void quickSortNoneRecursive(int a[], int n){
int i, j, low, high, temp;
int top = 0;
stackNode *st = (stackNode*) malloc(sizeof(stackNode)*SCALE);
if( !st ){
printf("内存分配故障!");
exit(0);
}
st[top].low = 0;
st[top].high = n-1;
while( top > -1){
low = st[top].low;
high = st[top].high;
top--;
i = low;
j = high;
if( low < high ){
temp = a[low];
while( i < j){
while(i<j && a[j]>=temp){
j--;
}
a[i] = a[j];
while(i<j && a[i]<=temp){
i++;
}
a[j] = a[i];
}
a[i] = temp;
if(i <= j){
top++;
st[top].low = low;
st[top].high = i-1;
top++;
st[top].low = ++i;
st[top].high = high;
}
}
}
}
//快排非递归算法
void merge(int a[], int low, int center, int high){//这里的merge与教科书上有不同。我们用两个数组L[],R[]来存储a[]需要合并的两段
int i = 0;
int j = 0;
int k = 0;
int count = 0;
if(low >= high) return;
int m = center - low + 1;
int n = high - center;
int *L = (int *)malloc(sizeof(int)*SCALE);
int *R = (int *)malloc(sizeof(int)*SCALE);
if(!L || !R){
printf("归并排序merge()内存分配故障!");
exit(0);
}
for( count=0; count<=m; count++){
L[count] = a[low+count];
}
for( int count=0; count<=n; count++){
R[count] = a[low+count+m];
}
for(i=0,j=0,k=low; i<m&&j<n; ++k){
if( L[i] <= R[j] ){
a[k] = L[i++];
}
else{
a[k] = R[j++];
}
}
while(i < m){
a[k++] = L[i++];
}
while(j < n){
a[k++] = R[j++];
}
free(L);
free(R);
}
void mSort(int a[], int low, int high){
int center;
if(low < high){
center = (low + high) / 2;
mSort(a, low, center);
mSort(a, center+1, high);
merge(a, low, center, high );
}
}
void mergeSortRecursive(int a[], int n){
mSort(a, 0, n-1);
}
//归并递归算法
void mergeSortNoneRecursive(int a[], int n){
int t = 2;
int i = 0;
while( t <= (n-1)){
i = 0;
while((i+t-1) <= (n-1)){
merge(a, i, i+t/2-1, i+t-1);
i += t;
}
t *= 2;
}
merge(a, 0, t/2-1, n-1);
}
//归并非递归算法
int randomNumber(int i, int j){
int v = 0;
if( i != j){
v = rand()%(j-i) + i;
}
else{
v = i;
}
return v;
}
void swap(int a[], int i, int j){
int temp;
temp = a[i];
a[i] = a[j];
a[j] = temp;
}
int modifiedPartition(int a[], int low, int high){
int pivot = randomNumber(low, high);
int temp = a[pivot];
while(low < high){
while(low<high && a[high]>=temp){//这里的“=”必须加,因为当temp的值等于a[high]或a[low]时,不加等号,程序无法往继续执行,就会
high--; //在两个相等值之间跳动无法继续执行
}
while(low<high && a[low]<=temp){
low++;
}
swap(a, low, high);
}
a[low] = temp;
return low;
}
void modifiedQSort(int a[], int low, int high){
if( low < high){
int pivotkey = modifiedPartition( a, low, high );
modifiedQSort( a, low, pivotkey-1 );
modifiedQSort( a, pivotkey+1, high);
}
}
void modifiedQuickSortRecursive(int a[], int n){
modifiedQSort(a, 0, n-1);
}
// 改进后的快排递归算法
void modifiedQuickSortNoneRecursive(int a[], int n){
int i, j, low, high, temp, pivotKey;
int top = 0;
stackNode *st = (stackNode*)malloc(sizeof(stackNode)*SCALE);
st[top].low = 0;
st[top].high = n-1;
while(top > -1){
low = st[top].low;
high = st[top].high;
top--;
i = low;
j = high;
if(low < high){
pivotKey = randomNumber(i, j);
temp = a[pivotKey];
while(i < j){
while(i<j && a[j]>=temp){
j--;
}
while(i<j && a[i]<=temp){
i++;
}
swap(a, i, j);
}
a[i] = temp;
if(i<=j){
top++;
st[top].low = low;
st[top].high = i-1;
top++;
st[top].low = j+1;
st[top].high = high;
}
}
}
}
//改进后的快排非递归算法
主函数实现:”main.c”
#include "h1.h"
int main(){
int i = 0;
timeNode t[6];
int *a = (int*)malloc(sizeof(int) * SCALE);
if( !a ){
printf("内存申请失败!");
return 0;
}
for(i=0; i<SCALE; i++){
a[i] = rand()%SCALE;
}//产生将要进行排序的随机数
for(int i=0; i<50; i++){
printf("%d ", a[i]);
}
t[0].start = clock();
//quickSortRecursive( a, SCALE); //快排递归算法
t[0].end = clock();
t[1].start = clock();
//quickSortNoneRecursive(a, SCALE);
t[1].end = clock();
t[2].start = clock();
//mergeSortRecursive(a, SCALE);
t[2].end = clock();
t[3].start = clock();
//mergeSortNoneRecursive(a, SCALE);
t[3].end = clock();
t[4].start = clock();
//modifiedQuickSortRecursive(a, SCALE);
t[4].end = clock();
t[5].start = clock();
modifiedQuickSortNoneRecursive(a, SCALE);
t[5].end = clock();
printf("\n");
for(i=0; i<50; i++){
printf("%d ", a[i]);
}
printf("\n");
for(i=0; i<6; i++){
printf("%d 毫秒\n", (t[i].end-t[i].start));
}
return 0;
}