C语言实现九种排序

C语言实现九种排序

头文件

#ifndef _MYSORT_H_
#define _MYSORT_H_
/*网站 : sorting.at*/

typedef enum {UP,DOWN} SORTWAY;


void myswap(int *a,int *b);
void arrayswap(int a[],int i,int j);



void myprint(int a[],int len);

/************************[r_bubble_sort]************************************
函数功能:
				冒泡排序 ===>非递归实现
函数参数:
函数返回值:
*************************[r_bubble_sort]************************************/
void bubble_sort(int array[], int len_array,SORTWAY way);

/************************[r_bubble_sort]************************************
函数功能:
				冒泡排序 ===>递归实现
函数参数:
函数返回值:
*************************[r_bubble_sort]************************************/
void r_bubble_sort(int array[], int len_array,SORTWAY way);




/************************[cocktail_sort]************************************
函数功能:
				鸡尾酒排序(双向冒泡排序) ===>非递归实现
函数参数:
函数返回值:
*************************[cocktail_sort]************************************/
void cocktail_sort(int array[], int len_array,SORTWAY way);
/************************[r_cocktail_sort]************************************
函数功能:
				鸡尾酒排序(双向冒泡排序) ===>递归实现
函数参数:
函数返回值:
*************************[r_cocktail_sort]************************************/
void r_cocktail_sort(int array[], int left,int right,SORTWAY way);



/************************[selection_sort]************************************
函数功能:
				选择排序 ===>非递归实现
				算法思想:在数组中找最小或最大数的下标,其值与数组第一个元素交换
函数参数:
函数返回值:
*************************[selection_sort]************************************/
void selection_sort(int array[], int len_array,SORTWAY way);
void r_selection_sort(int array[], int len_array,int limit_index,SORTWAY way);


/************************[Insertion_sort]************************************
函数功能:
				插入排序 ===>非递归实现
				算法思想:将一个数插入到有序数组中
							1、复制性移动
							2、插入数据
			
函数参数:
				[in]array     :  需要排序的数组
				[in]len_array :
				[in]way       :
函数返回值:
*************************[Insertion_sort]************************************/
void Insertion_sort(int array[], int len_array,SORTWAY way);


/************************[Insertion_DIV_sort]************************************
函数功能:
				插入排序 ===>非递归实现 (二分法)
				算法思想:将一个数插入到有序数组中
							1、复制性移动
							2、插入数据
			
函数参数:
				[in]array     :  需要排序的数组
				[in]len_array :	 
				[in]way       :
函数返回值:
*************************[Insertion_DIV_sort]************************************/
void Insertion_DIV_sort(int array[], int len_array,SORTWAY way);

/************************[Shell_sort]************************************
函数功能:
				希尔排序 ===>分组插入排序
				算法思想:	多次将待排序数组分组,每组进行直接插入排序
							将一个数插入到有序数组中
							1、复制性移动
							2、插入数据
			
函数参数:
				[in]array     :  需要排序的数组
				[in]len_array :	 
				[in]way       :
函数返回值:
*************************[Shell_sort]************************************/
void Shell_sort(int array[], int len_array,SORTWAY way);

/************************[Heap_sort]************************************
函数功能:
				堆排序 
				算法思想:
						1、将数组调整成二叉堆的形式  (从第一个非叶结点的结点开始,从右到左,从下到上进行跳调整)
						2、进行排序:将第一个节点的值与最后一个节点交换,然后“去掉”(长度减一)这个节点,在进行堆调整。重复操作至长度为1
函数参数:
				[in]array     :  需要排序的数组
				[in]len_array :	 
				[in]way       :
函数返回值:
*************************[Heap_sort]************************************/
void Heap_sort(int array[], int len_array,SORTWAY way);

/************************[merge_sort]************************************
函数功能:
				按顺序合并两个数组

函数参数:
				[in]array     :  需要排序的数组
				[in]len_array :	 
				[in]way       :
函数返回值:
*************************[merge_sort]************************************/
void merge(int array[],int left,int mid,int right,int*tmp,SORTWAY way);
/************************[merge_sort]************************************
函数功能:
				归并排序  ===>递归实现
				算法思想:
						 
函数参数:		
				[in]array     :  需要排序的数组
				[in]left      :	 数组的左边界
				[in]right     :	 数组的右边界
				[in]tmp       :  临时数组 ,用来暂存合并后的数据
				[in]way       :  way等于UP   为升序
								 way等于DOWN 为降序
函数返回值:
*************************[merge_sort]************************************/
void r_merge_sort(int array[], int left,int right,int tmp[],SORTWAY way);


/************************[partition]************************************
函数功能:
				分区确定基准值的下标
				
函数参数:
				[in]array     :  需要分区的数组
				[in]left      :	 数组的左边界
				[in]right     :	 数组的右边界
				[in]way       :  way等于UP   为升序
								 way等于DOWN 为降序
函数返回值:
				返回分区后的基准值的下标
*************************[partition]************************************/
int partition(int array[],int left,int right,SORTWAY way);
/************************[r_quick_sort]************************************
函数功能:
				快速排序  ‘=====>递归实现
				算法思想:选取一个基准值,将数组按基准值分成两部分,一部分比他小,一部分比他大
						  核心操作就是分区,确定基准值的位置 ,然后左右两边在进行快排

函数参数:
				[in]array     :  需要排序的数组
				[in]left      :	 数组的左边界
				[in]right     :	 数组的右边界
				[in]way       :  way等于UP   为升序
								 way等于DOWN 为降序
函数返回值:
				
*************************[r_quick_sort]************************************/
void r_quick_sort(int array[], int left,int right,SORTWAY way);

#endif//_MYSORT_H_

C文件

#include <stdio.h>
#include <stdlib.h>
#include "mysort.h"

void myswap(int *a,int *b)
{
	int tmp = *a;
	*a 		= *b;
	*b 		= tmp ;
}

void arrayswap(int a[],int i,int j)
{
	int tmp = a[i];
	a[i]    = a[j];
	a[j]    = tmp;
}

void myprint(int a[],int len)
{	
	int i;
	for(i=0;i<len;i++)
		printf("%4d",a[i]);
	printf("\n");
}


void bubble_sort(int array[], int len_array,SORTWAY way)
{
	
	int i,j;
	for(i=0;i<len_array-1;i++)
	{
		for(j=0;j<len_array-1-i;j++)
		{
		
			if(UP == way) //升序
			{
				if(array[j]<array[j+1])
				{
				    int tmp        = array[j];
					array[j]   = array[j+1];
					array[j+1] = tmp; 
				}
			}
			else
			{
				if(array[j]>array[j+1])
				{
				    int tmp        = array[j];
					array[j]   = array[j+1];
					array[j+1] = tmp; 
				}
			}
		}
	}
}


void r_bubble_sort(int array[], int len_array,SORTWAY way)
{
	
	int i;
	for(i=0;i<len_array-1-i;i++)
	{
		if(UP == way)
		{
			if(array[i]<array[i+1])
			{
				int tmp    = array[i];
				array[i]   = array[i+1];
				array[i+1] = tmp; 
			}
		}
		else
		{
			if(array[i]>array[i+1])
			{
				int tmp    = array[i];
				array[i]   = array[i+1];
				array[i+1] = tmp; 
			}
		}
	}
	
	r_bubble_sort(array,len_array-1,way);

}



void cocktail_sort(int array[], int len_array,SORTWAY way)
{
	
	int left  = 0;
	int right = len_array-1;
	
	
	while(left < right)
	{
		if(UP == way)
		{
			//从左到右遍历,找到最大的数,放到最后面
			int i;
			for(i = left ;i<right;i++)
			{
				if(array[i]>array[i+1])
				{
					myswap(&array[i],&array[i+1]);
				}
			}
			right--;
			
			//从右到左遍历,找到最小的数,放到最前面	
			for(i = right ;i>left;i--)
			{
				if(array[i]<array[i-1])
				{
					myswap(&array[i],&array[i-1]);
				}
			}
			left++;
		}
		else
		{
			//从左到右遍历,找到最小的数,放到最后面
			int i;
			for(i = left ;i<right;i++)
			{
				if(array[i]<array[i+1])
				{
					myswap(&array[i],&array[i+1]);
				}
			}
			right--;
			
			//从右到左遍历,找到最大的数,放到最前面
			for(i = right ;i>left;i--)
			{
				if(array[i]>array[i-1])
				{
					myswap(&array[i],&array[i-1]);
				}
			}
			left++;
		}

	}	
}

void r_cocktail_sort(int array[], int left,int right,SORTWAY way)
{
	//退出条件
	if(left >= right)
		return;
	
	
	if(UP == way)
	{
		//从左到右遍历,找到最大的数,放到最后面
		int i;
		for(i = left ;i<right;i++)
		{
			if(array[i]>array[i+1])
			{
				myswap(&array[i],&array[i+1]);
			}
		}
		right--;
		
		//从右到左遍历,找到最小的数,放到最前面	
		for(i = right ;i>left;i--)
		{
			if(array[i]<array[i-1])
			{
				myswap(&array[i],&array[i-1]);
			}
		}
		left++;
	}
	else
	{
		//从左到右遍历,找到最小的数,放到最后面
		int i;
		for(i = left ;i<right;i++)
		{
			if(array[i]<array[i+1])
			{
				myswap(&array[i],&array[i+1]);
			}
		}
		right--;
		
		//从右到左遍历,找到最大的数,放到最前面
		for(i = right ;i>left;i--)
		{
			if(array[i]>array[i-1])
			{
				myswap(&array[i],&array[i-1]);
			}
		}
		left++;
	}
	
	r_cocktail_sort(array,left,right,way);
}


void selection_sort(int array[], int len_array,SORTWAY way)
{	
	//找最小元素下标
	int i,j ;
	for(i=0;i<len_array-1;i++)
	{
		if(UP == way)
		{
			int min = i;
			for(j = i+1;j<len_array;j++)
			{
				if(array[min]>array[j])
					min = j;
			}
			//与数组第一个元素交换
			if(min != i)
				arrayswap(array,min,i);
		}
		else
		{
			int max = i;
			for(j = i+1;j<len_array;j++)
			{
				if(array[max]<array[j])
					max = j;
			}
			//与数组第一个元素交换
			if(max != i)
				arrayswap(array,max,i);
		}
		
	}	
}

void r_selection_sort(int array[], int len_array,int limit_index,SORTWAY way)
{	

	if(limit_index == len_array-1)
		return;

	int i;
	//找最小元素下标
	if(UP == way)
	{
		int min = limit_index ;
		for(i = min+1;i<len_array;i++)
		{
			if(array[min]>array[i])
				min = i;
		}
		//与数组第一个元素交换
		if(min != limit_index)
			arrayswap(array,min,limit_index);
	}
	else
	{
		int max = limit_index;
		for(i = max+1;i<len_array;i++)
		{
			if(array[max]<array[i])
				max = i;
		}
		//与数组第一个元素交换
		if(max != limit_index)
			arrayswap(array,max,limit_index);
	}
	limit_index++;
	r_selection_sort(array,len_array,limit_index,way);
}



void Insertion_sort(int array[], int len_array,SORTWAY way)
{
	int i,j;
	for(i=1;i<len_array;i++)
	{
		j = i-1;
		int tmp = array[j+1];		
		while(j>=0)
		{
			if(UP == way)
			{
				//找到第一个比他小的数
				if(tmp >= array[j])
				{
					break;	
				}
				else
				{
					array[j+1] = array[j];	
					j--;
				}
			}
			else
			{
				//找到第一个比他大的数
				if(tmp <= array[j])
				{
					break;	
				}
				else
				{
					array[j+1] = array[j];	
					j--;
				}
			}
			
		}
		//插入数据
		array[j+1] = tmp;
	}
	
}

void Insertion_DIV_sort(int array[], int len_array,SORTWAY way)
{
	
	//二分法找到要插入的位置
	int i;
	for(i=1;i<len_array;i++)
	{
		int left  = 0;
		int right = i-1;
	
		
		int tmp = array[i]; //保存待插入的数据
		while(left <= right )
		{
			int mid   = (left+right)/2;
			if(UP == way)
			{
				if(tmp < array[mid] )
					right  = mid-1;
				else
					left   = mid+1;			
			}
			else
			{
				if(tmp >array[mid])
					right  = mid-1;
				else
					left   = mid+1;					
			}
		}
		
		//复制性移位
		int j;
		for(j=i-1;j>=left;j--)
			array[j+1] = array[j];
		
		
		//插入数据
		array[left] = tmp;
		
	}		
}



void Shell_sort(int array[], int len_array,SORTWAY way)
{
	
	int gap = 0 ;
	while(gap < len_array)
	{
		gap = gap*3+1;
	}
	
	
	while(gap>0)
	{
		int  i;
		for(i = gap;i<len_array;i++)
		{
			int j = i-gap;	//找到该数据(i)所在组的前一个数据(j)
			
			int tmp = array[i];//保存待插入的数据
			
			//找到要插入位置的前一个位置
			while(j>=0 )
			{
				if(UP == way)
				{
					if(tmp < array[j])
					{
						array[j+gap] = array[j];
						j-=gap;
					}
					else
					{
						break;
					}
				}
				else
				{
					if(tmp > array[j])
					{
						array[j+gap] = array[j];
						j-=gap;
					}
					else
					{
						break;
					}
				}
					
			}
			
			//插入数据
			array[j+gap] = tmp;
			
			
		}
		gap /= 3;
	}
	
	
}


//调整堆
void r_herify(int array[],int index,int len_array,SORTWAY way)
{
	int lchild_index = 2*index+1;
	int rchild_index = 2*index+2;
	
	if(UP == way) //升序,大顶堆
	{
		int max = index;
		if(lchild_index<len_array && array[max] < array[lchild_index])
			max = lchild_index;
		
		if(rchild_index<len_array && array[max] < array[rchild_index])
			max = rchild_index;
		
		if(max != index)	
		{
			arrayswap(array,max,index);
			r_herify(array,max,len_array,way);
		}
	}
	else	//降序,小顶堆
	{
		int min = index;
		if(lchild_index<len_array && array[min] > array[lchild_index])
			min = lchild_index;
		
		if(rchild_index<len_array && array[min]> array[rchild_index])
			min = rchild_index;
		
		if(min != index)	
		{
			arrayswap(array,min,index);
			r_herify(array,min,len_array,way);
		}
	}
}
void Heap_sort(int array[], int len_array,SORTWAY way)
{
	//建堆:从非叶节点开始,把每一个结点搞成大顶堆
	int i;
	for(i=len_array/2-1;i>=0;i--)
	{
		r_herify(array,i,len_array,way);
	}	
	
	//排序 ==> 交换 调整
	int last = len_array;
	for(i = len_array-1;i >0;i--)
	{		
		arrayswap(array,0,i);
		last--;
		r_herify(array,0,last,way);
	}
	
}



void merge(int array[],int left,int mid,int right,int*tmp,SORTWAY way)
{
	int i = left; //左边数组下标
	int j = mid+1;//右边数组下标
	int k = 0;	  //临时数组下标
	if(UP == way)
	{
		while(i<=mid && j<= right)
		{
			if(array[i] < array[j])
				tmp[k++] = array[i++];
			else
				tmp[k++] = array[j++];
		}
		
		while(i<=mid)
			tmp[k++] = array[i++];
		
		while(j<=right)
			tmp[k++] = array[j++];
	}
	else
	{
		while(i<=mid && j<= right)
		{
			if(array[i] > array[j])
				tmp[k++] = array[i++];
			else
				tmp[k++] = array[j++];
		}
		
		while(i<=mid)
			tmp[k++] = array[i++];
		
		while(j<=right)
			tmp[k++] = array[j++];
	}
	
	//将数据放到原数组中
	for(i=0;i<k;i++)
	{
		array[left+i] = tmp[i];
	}
		
}
void r_merge_sort(int array[], int left,int right,int tmp[],SORTWAY way)
{

	if(left>=right)
		return;
			
	int mid  = (left+right)/2;
	//左边数组归并排序
	r_merge_sort(array,left,mid,tmp,way);
	
	//右边数组归并排序
	r_merge_sort(array,mid+1,right,tmp,way);
	
	//合并数组归并排序
	merge(array,left,mid,right,tmp,way);
	

}


//分区
int partition(int array[],int left,int right,SORTWAY way)
{
	int pivot = array[right]; //选取最右边的为基准值
	
	while(left<right)
	{
		//int len = right - left;//待操作数组长度
		if(UP == way)
		{
			while(array[left] <= pivot && left<right)
			{
				left++;
			}
			if(left<right)
			{
				array[right] = array[left];
				right--;
			}
			while(array[right] >= pivot && left<right)
			{
				right--;
			}
			if(left<right)
			{
				array[left] = array[right];
				left++;
			}	
		}
		else
		{
			while(array[left] >= pivot && left<right)
			{
				left++;
			}
			if(left<right)
			{
				array[right] = array[left];
				right--;
			}
			while(array[right] <= pivot && left<right)
			{
				right--;
			}
			if(left<right)
			{
				array[left] = array[right];
				left++;
			}	
		}
		
	}	
	array[left] = pivot;
	
	return left;
}

void r_quick_sort(int array[], int left,int right,SORTWAY way)
{
	if(left<right)
	{
		//分区并确定基准值的下标
		int pivotIndex = partition(array,left,right,way);
		//对左半部分进行快速排序
		r_quick_sort(array,left,pivotIndex-1,way);
		//对右半部分进行快速排序	
		r_quick_sort(array,pivotIndex+1,right,way);
	}
}



测试主函数

#include <stdio.h>
#include "mysort.h"



int main()
{
	int a[]={1,5,3,6,8,4,6,5,4};
	
	int len = sizeof(a)/sizeof(a[0]);

	
	myprint(a,len);
	printf("冒泡排序**********************\n");
	bubble_sort(a,len,UP);
	myprint(a,len);
	bubble_sort(a,len,DOWN);
	myprint(a,len);
	
	printf("鸡尾酒排序**********************\n");
	cocktail_sort(a,len,UP);
	myprint(a,len);	
	cocktail_sort(a,len,DOWN);
	myprint(a,len);
	
	r_cocktail_sort(a,0,len-1,UP);
	myprint(a,len);
	r_cocktail_sort(a,0,len-1,DOWN);
	myprint(a,len);
	
	printf("选择排序**********************\n");
	selection_sort(a,len,UP);
	myprint(a,len);
	r_selection_sort(a,len,0,DOWN);
	myprint(a,len);

	
	printf("插入排序**********************\n");
	Insertion_sort(a,len,UP);
	myprint(a,len);
	Insertion_sort(a,len,DOWN);
	myprint(a,len);
	
	printf("二分法插入排序**********************\n");	
	Insertion_DIV_sort(a,len,UP);
	myprint(a,len);	
	Insertion_DIV_sort(a,len,DOWN);
	myprint(a,len);
	
	printf("希尔分组插入排序**********************\n");	
	Shell_sort(a,len,UP);
	myprint(a,len);	
	Shell_sort(a,len,DOWN);
	myprint(a,len);	
	
	printf("堆排序****************************\n");	
	Heap_sort(a,len,UP);
	myprint(a,len);	
	Heap_sort(a,len,DOWN);
	myprint(a,len);	
	
	printf("归并排序****************************\n");	
	int tmp[10] ={0};
	r_merge_sort(a,0,len-1,tmp,UP);
	myprint(a,len);	
	
	r_merge_sort(a,0,len-1,tmp,DOWN);
	myprint(a,len);

	printf("快速排序****************************\n");	
	r_quick_sort(a,0,len-1,UP);
	myprint(a,len);	
	
	r_quick_sort(a,0,len-1,DOWN);
	myprint(a,len);	
	
	
	
	
	return 0;

}
  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值