C语言实现十种常见排序算法

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <malloc.h>

#define SORT_NUM	10
int after_sort[SORT_NUM];

int* bubbleSort(int pre_sort[])
{
	int i = 0,j = 0;
	int tmp = 0;

	memcpy(after_sort,pre_sort,sizeof(after_sort));
	for(i = 0; i < SORT_NUM - 1;i++)
	{
		for(j = i+1;j < SORT_NUM;j++)
		{
			if(after_sort[i] > after_sort[j])
			{
				tmp = after_sort[i];
				after_sort[i] = after_sort[j];
				after_sort[j] = tmp;
			}	
		}
	}
	return after_sort;
}

/*================================================================*/
int* SelectSort(int pre_sort[])
{
	int i = 0,j = 0;
	int tmp = 0;
	int MinIndex = 0;
	
	memcpy(after_sort,pre_sort,sizeof(after_sort));
	for(i = 0; i < SORT_NUM - 1;i++)
	{
		MinIndex = i;
		for(j = i + 1;j < SORT_NUM;j++)
		{
			if(after_sort[MinIndex] > after_sort[j])
			{
				MinIndex = j;
			}
		}

		if(MinIndex != i)
		{
			tmp = after_sort[MinIndex];
			after_sort[MinIndex] = after_sort[i];
			after_sort[i] = tmp;
		}
	}
	
	return after_sort;
}

/*================================================================*/
int* InsertSort(int pre_sort[])
{
	int i = 0;
	int tmp = 0, p = 0;
	
	memcpy(after_sort,pre_sort,sizeof(after_sort));

	for(i = 1;i < SORT_NUM;i++)
	{
		tmp = after_sort[i];
		p = i - 1;
		
		while(p >= 0 && tmp < after_sort[p])
		{
			after_sort[p+1] = after_sort[p]; //比较大的元素向后挪一位,腾出空间
			p--;
		}

		after_sort[p + 1] = tmp;
	}
	
	return after_sort;
}

/*================================================================*/
int* ShellSort(int pre_sort[])
{
	int i = 0,j = 0,p = 0,tmp = 0;
	memcpy(after_sort,pre_sort,sizeof(after_sort));
	int step = 0; 	
	
	for(step = SORT_NUM / 2; step >= 1; step = step / 2)
	{
		for(i = 0; i < step; i++)
		{
			for(j = i + step; j < SORT_NUM; j = j + step)//单独一次的插入排序
			{	
				if(after_sort[j] < after_sort[j - step])
				{
					tmp = after_sort[j];
					p = j - step;
					while(p >= 0 && after_sort[p] > tmp)
					{
						after_sort[p + step] = after_sort[p];
						p = p - step;
					}
					after_sort[p + step] = tmp;
				}
			}
		}
	}


	return after_sort;
}

/*================================================================*/
void merge(int arr[], int low, int mid, int high)
{
	int i, k;
	int *tmp = (int *)malloc((high-low+1)*sizeof(int));
	//申请空间,使其大小为两个
	int left_low = low;
	int left_high = mid;
	int right_low = mid + 1;
	int right_high = high;

	for(k=0; left_low<=left_high && right_low<=right_high; k++)
	{  // 比较两个指针所指向的元素
		if(arr[left_low]<=arr[right_low])
		{
			tmp[k] = arr[left_low++];
		}
		else
		{
			tmp[k] = arr[right_low++];
		}
	}

	if(left_low <= left_high)
	{  //若第一个序列有剩余,直接复制出来粘到合并序列尾
		//memcpy(tmp+k, arr+left_low, (left_high-left_low+l)*sizeof(int));
		for(i=left_low;i<=left_high;i++)
		{
			tmp[k++] = arr[i];
		}
	}

	if(right_low <= right_high)
	{
		//若第二个序列有剩余,直接复制出来粘到合并序列尾
		//memcpy(tmp+k, arr+right_low, (right_high-right_low+1)*sizeof(int));
		for(i=right_low; i<=right_high; i++)
		{	
			tmp[k++] = arr[i];
		}
	}

	for(i=0; i<high-low+1; i++)
	{
		arr[low+i] = tmp[i];
	}
	free(tmp);
}

void MergeSort(int arr[], unsigned int first, unsigned int last)
{
	int mid = 0;
	if(first < last)
	{
		mid = (first+last) / 2; /* 注意防止溢出 */

		MergeSort(arr, first, mid);
		MergeSort(arr, mid+1,last);

		merge(arr,first,mid,last);
	}
}


/*================================================================*/
void QuickSort(int arr[], int low, int high)
{
    if (low < high)
    {
        int i = low;
        int j = high;
        int k = arr[low];
        while (i < j)
        {
            while(i < j && arr[j] >= k)     // 从右向左找第一个小于k的数
            {
                j--;
            }
 
            if(i < j)
            {
                arr[i++] = arr[j];
            }
 
            while(i < j && arr[i] < k)      // 从左向右找第一个大于等于k的数
            {
                i++;
            }
 
            if(i < j)
            {
                arr[j--] = arr[i];
            }
        }
 
        arr[i] = k;
 
        // 递归调用
        QuickSort(arr, low, i - 1);     // 排序k左边
        QuickSort(arr, i + 1, high);    // 排序k右边
    }
}

/*================================================================*/
void HeapAdjust(int pre_sort[],int i,int N)//一次筛选的过程
{
	int child = 0;
	int Tmp = 0;

	for (Tmp = pre_sort[i]; 2*i+1 < N; i = child)
	{
		child = 2*i+1; //注意数组下标是从0开始的,所以左孩子的求发不是2*i
		if (child != N - 1 && pre_sort[child + 1] > pre_sort[child])
		{
		    ++child;                //找到最大的儿子节点
		}
			
		if (Tmp < pre_sort[child])
		{
			pre_sort[i] = pre_sort[child];
		}
		else
		{
		    break;
		}
  	}
	pre_sort[i] = Tmp;
}

void HeapSort(int pre_sort[],int n)
{
	int temp,i,j;
	for(i = n / 2; i>=0; --i)//通过循环初始化顶堆
	{
		HeapAdjust(pre_sort,i,n);
	}
	for(i = n - 1; i>0; --i)
	{
		temp = pre_sort[0];
		pre_sort[0] = pre_sort[i];
		pre_sort[i] = temp;//将堆顶记录与未排序的最后一个记录交换
		HeapAdjust(pre_sort,0,i);//重新调整为顶堆
	}
}
/*================================================================*/

int* CountSort(int pre_sort[], int n, int max_data)
{
	int *tmp, *end;
	int i;

	memcpy(after_sort,pre_sort,sizeof(after_sort));
	tmp = (int *)malloc(sizeof(int)*max_data);
/*临时数组,注意它的大小是待排序序列中值最大的那个。如假定该排序序列中最大值为1000000,则该数组需要1000000*sizeof(int)个存储单元*/

	end = (int *)malloc(sizeof(int)*n);  /*存放排序结果的数组*/
	for (i = 0; i < max_data; i++)
	{	
		tmp[i] = 0;                 /*初始化*/
	}

	for (i = 0; i < n; i++)
	{
		tmp[after_sort[i]] += 1;         	/*统计数组A中每个值为i的元素出现的次数*/
	}

	for (i = 1; i < max_data; i++)
	{
		tmp[i] = tmp[i - 1] + tmp[i];  	 	/*确定值为i的元素在数组c中出现的位置*/
	}

	for (i = n - 1; i >= 0; i--)
	{
		end[tmp[after_sort[i]] - 1] = after_sort[i];   /*对A数组,从后向前确定每个元素所在的最终位置;*/
		tmp[after_sort[i]] -= 1;
	}

	for (i = 0; i < n; i++)
	{
		after_sort[i] = end[i];            	/*这个目的是返回A数组作为有序序列*/
	}
	free(tmp);
	free(end);

	return after_sort;
}


typedef struct node {
	int key;
	struct node *next;
}KeyNode;

int* BucketSort(int pre_sort[],int max)
{
	int i,j;
	memcpy(after_sort,pre_sort,sizeof(after_sort));

	int *bucket;
	if((bucket = (int*)malloc(max*sizeof(int))) == NULL)
	{
		printf("malloc failed!\r\n");
	}
	memset(bucket,0x00,sizeof(int)*max);
	
	for(i = 0; i < SORT_NUM;i++)
	{
		bucket[after_sort[i]]++;	
	}
	
	for(i = 0,j = 0;i < max;i++)
	{
		while((bucket[i]--) > 0)
		{
			after_sort[j++] = i;
		}
	}
	free(bucket);	

	return after_sort;
}

int GetNumInPos(int num,int pos)
{
	int temp = 1;
	for (int i = 0; i < pos - 1; i++)
		temp *= 10;
    
	return (num / temp) % 10;
}

int* RadixSort(int pre_sort[])
{
	int i = 0;
	memcpy(after_sort,pre_sort,sizeof(after_sort));
	
	int *radixArrays[SORT_NUM];    //分别为0~9的序列空间
	for (i = 0; i < SORT_NUM; i++)
	{
		radixArrays[i] = (int *)malloc(sizeof(int) * (SORT_NUM + 1));
		radixArrays[i][0] = 0;    //index为0处记录这组数据的个数
	}
	
	for (int pos = 1; pos <= SORT_NUM; pos++)    //从个位开始到31位
	{
		for (int i = 0; i < SORT_NUM; i++)    //分配过程
		{
			int num = GetNumInPos(after_sort[i], pos);
			int index = ++radixArrays[num][0];
			radixArrays[num][index] = after_sort[i];
		}
        
		for (int i = 0, j =0; i < SORT_NUM; i++)    //收集
		{
			for (int k = 1; k <= radixArrays[i][0]; k++)
			{
				after_sort[j++] = radixArrays[i][k];
			}
			radixArrays[i][0] = 0;    //复位
		}
	}

	return after_sort;
}

int main(int argc,char**argv)
{
	int pre_sort[SORT_NUM] = {12,11,13,14,11,18,14,11,16,17};
	int *p = NULL;
	int i = 0;
	
	printf("****0**** before sort:\r\n");
	for(i = 0;i < sizeof(pre_sort) / sizeof(pre_sort[0]);i++)
	{
		printf("%d ",pre_sort[i]);
	}
	/*================================================================*/
	p = bubbleSort(pre_sort);
	printf("\r\n****1**** bubble sort: \r\n");
	for(i = 0;i < sizeof(pre_sort) / sizeof(pre_sort[0]);i++)
	{
		printf("%d ",*(p + i));
	}
	
	/*================================================================*/
	p = NULL;
	p = SelectSort(pre_sort);
	printf("\r\n****2**** select sort: \r\n");
	for(i = 0;i < sizeof(pre_sort) / sizeof(pre_sort[0]);i++)
	{
		printf("%d ",*(p + i));
	}
	/*================================================================*/
	p = NULL;
	p = InsertSort(pre_sort);
	printf("\r\n****3**** insert sort: \r\n");
	for(i = 0;i < sizeof(pre_sort) / sizeof(pre_sort[0]);i++)
	{
		printf("%d ",*(p + i));
	}
	/*================================================================*/
	p = NULL;
	p = ShellSort(pre_sort);
	printf("\r\n****4**** shell sort: \r\n");
	for(i = 0;i < sizeof(pre_sort) / sizeof(pre_sort[0]);i++)
	{
		printf("%d ",*(p + i));
	}
	/*================================================================*/
	memset(after_sort,0x00,sizeof(after_sort));	
	memcpy(after_sort,pre_sort,sizeof(after_sort));	
	MergeSort(after_sort,0,SORT_NUM-1);  
	printf("\r\n****5**** merge sort: \r\n");
	for(i = 0;i < sizeof(after_sort) / sizeof(after_sort[0]);i++)
	{
		printf("%d ",after_sort[i]);
	}
	
	/*================================================================*/
	memcpy(after_sort,pre_sort,sizeof(after_sort));
	QuickSort(after_sort,0,SORT_NUM - 1);
	printf("\r\n****6**** quick sort: \r\n");
	for(i = 0;i < sizeof(after_sort) / sizeof(after_sort[0]);i++)
	{
		printf("%d ",after_sort[i]);
	}
	/*================================================================*/
	memset(after_sort,0x00,sizeof(after_sort));
	memcpy(after_sort,pre_sort,sizeof(after_sort));
	HeapSort(after_sort,SORT_NUM);
	printf("\r\n****7**** heap sort: \r\n");
	for(i = 0;i < sizeof(after_sort) / sizeof(after_sort[0]);i++)
	{
		printf("%d ",after_sort[i]);
	}	
	/*================================================================*/
	memset(after_sort,0x00,sizeof(after_sort));
	p = NULL;
	p = CountSort(pre_sort,SORT_NUM,20);
	printf("\r\n****8**** count sort: \r\n");
	for(i = 0;i < sizeof(after_sort) / sizeof(after_sort[0]);i++)
	{
		printf("%d ",*(p + i));
	}				
	/*================================================================*/
	p = NULL;
	p = BucketSort(pre_sort,18 + 1);
	printf("\r\n****9**** bucket sort: \r\n");
	for(i = 0;i < sizeof(after_sort) / sizeof(after_sort[0]);i++)
	{
		printf("%d ",*(p + i));
	}	
	
	/*================================================================*/
	p = NULL;
	p = RadixSort(pre_sort);
	printf("\r\n****10**** radix sort: \r\n");
	for(i = 0;i < sizeof(after_sort) / sizeof(after_sort[0]);i++)
	{
		printf("%d ",*(p + i));
	}	

	printf("\r\n");
	return 0;
}

该工程经在ubuntu系统上进行编译运行,可输出正确结果,笔者水平有限,如有错误,请指出,共同学习。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值