C语言“排序”代码

C语言数据结构“排序”代码

冒泡排序
快速排序
归并排序
直接插入排序
希尔排序
选择排序
堆排序

//初始条件:将一个一维数组从小到大排序
//输入:一个一维数组arr和它的长度n
//输出:一个已经被排好序的数组 
void bubblesort(int arr[],int n){
	int temp;
	for(int j=n-1;j>0;j--){
		for(int i=0;i<j;i++){
			if(arr[i]>arr[i+1]){
				temp=arr[i+1];
				arr[i+1]=arr[i];
				arr[i]=temp;
				//sawp(arr[i+1],arr[i]);  //arr类型未知 
			}
		}
	}	
} 



//初始条件:在一个一维数组中设置两个哨兵,交换数字 
//输入:一维数组arr和开头、最后元素在数组中的位置begin、end(均>=0) 
//输出:经过一趟数字交换后的数组和哨兵最后的位置 
int quick(int arr[],int begin,int end){  
	int ins;//指标(哨兵) 
	int high,low;
	int temp;
	ins=arr[begin];
	low=begin;
	high=end;
	while(low<high){
		while(low<high&&arr[high]>=ins){
			high--;
		}
		arr[low]=arr[high];  //不需要将两者的值交换,因为这样只会缺失ins的值 
		while(low<high&&arr[low]<=ins){
			low++;
		}
		arr[high]=arr[low];
	}
	arr[low]=ins;  //将ins值补充上 
	return high; 	
}

//初始条件:将一个一维数组通过快速排序(完成quick函数的迭代) 
//输入:一维数组arr和开头、最后元素在数组中的位置begin、end(均>=0) 
//输出:一个已排好序的数组 
void quicksort(int arr[],int begin,int end){
	int par=quick(arr,begin,end);
	if(par>begin+1){
		quicksort(arr,begin,par-1);
	}
	if(par<end-1){
		quicksort(arr,par+1,end);
	}
}

//初始条件:将两个有序的小组合成一个有序的大组 
//输入:一维数组arr和开头、中间、最后元素在数组中的位置low、mid、high(均>=0) 
//输出:有序的数组low~high部分 
void merge(int arr[],int low,int mid,int high){
	int insarr[high-low+10];    //多定义一些大小,防止意外 
	int i,j,k;
	for(i=low;i<=high;i++){
		insarr[i]=arr[i];
	}
	i=low;
	j=mid+1;
	k=low;
	while(i<=mid&&j<=high){
		if(insarr[i]<insarr[j]){
			arr[k]=insarr[i];
			k++;
			i++;
		}
		else{
			arr[k]=insarr[j];
			k++;
			j++;
		}
	}
	while(i<=mid){   //补充没有输入完的部分 
		arr[k]=insarr[i];
		k++;
		i++;
	}	
	while(j<=high){  //两个while循环有且只执行一个 
		arr[k]=insarr[j];
		k++;
		j++;
	}
}

//初始条件:将一个一维数组通过递归merge函数完成归并排序 
//输入:一维数组arr和开头、最后元素在数组中的位置(均>=0) 
//输出:一个通过归并排序的数组 
void mergesort(int arr[],int begin,int end){
	int mid;
	if(end>begin){  //若begin=end,返回上一次递归 
		mid=(begin+end)/2;
		mergesort(arr,begin,mid); //不断分化 
		mergesort(arr,mid+1,end); //分化到上面begin=end结束,执行下一条语句 
		merge(arr,begin,mid,end);
	}
}

//初始条件:将一个一维数组通过直接插入排序 
//输入:一维数组arr和数组长度n 
//输出:一个完成直接插入排序的数组 
void insertsort(int arr[],int n){  //和冒泡排序原理有些相似 
	int i,j,ins;  //ins哨兵,和temp的作用差不多,做中间变量 
	for(i=1;i<n;i++){
		if(arr[i]<arr[i-1]){   //如果一个数组中一个元素的值小于上一元素的值 
			ins=arr[i];   //则将这个元素的值放入中间变量 
			for(j=i-1;ins<arr[j]&&j>=0;j--){  //寻找这个元素应该放置的位置 
				arr[j+1]=arr[j];  //未找到时将大的元素后移(从i-1开始是因为i-1处的元素也需要后移,所以不能从i-2处开始) 
			}
			arr[j+1]=ins; //找到位置则停止循环,放入该值 
		}
	}
	//书中原本为:arr[0]作为哨兵,不做为数组的一部分 
}

//初始条件:将一个一维数组通过希尔排序 
//输入:一维数组arr和数组长度n 
//输出:一个完成希尔排序的数组 
void shellsort(int arr[],int n){  //分治+插入 
	int i,j,mid,ins;   //mid为跨步大小     例如:mid=2,则将0、2,4,6分为一组,1、3、5、7分为一组各自处理,然后mid=1、mid=0地处理 
	for(mid=n/2;mid>=1;mid=mid/2){
		for(i=mid+1;i<n;i++){
			if(arr[i]<arr[i-mid]){
				ins=arr[i];
				j=i-mid;
				while(j>=0&&arr[j]>ins){
					arr[j+mid]=arr[j];
					j=j-mid;
				}
				arr[j+mid]=ins;
			}
		}
	}
	//书中原本为:arr[0]不存储元素,而是存储哨兵 
} 

//初始条件:将一个一维数组通过选择排序 
//输入:一维数组arr和数组长度n 
//输出:一个完成选择排序的数组 
void selectsort(int arr[],int n){
	int min,temp;        //在所有数中选择一个最小的数,将其与数组最前的数进行交换 
	int i,j;
	for(i=0;i<n;i++){
		min=i;
		for(j=i+1;j<n;j++){
			if(arr[j]<arr[min]){    //min是动态的 
				min=j;
			}
		}
		if(min!=i){
			temp=arr[i];
			arr[i]=arr[min];
			arr[min]=temp;
		}
	}	
} 


//初始条件:将一个一维数组通过孩子间比较、与父亲节点比较,并以此原理调换迭代获得一个合法的堆 
//输入:一维数组arr且从第1位开始,第0位不存储数据;k为双亲节点(1~n/2);len为数组需要处理的部分的长度 
//输出:经过调整后,一个双亲结点比两个儿子节点都大的堆(两个孩子节点左右的大小位置没有规定) 
void headajust(int arr[],int k,int len){
	int i;
	arr[0]=arr[k]; //arr[0]暂存堆顶元素,arr[1]是堆真正的第一个元素 
	for(i=2*k;i<=len;i=i*2){
		if(i<len&&arr[i]<arr[i+1]){
			i++;     //得到两个子节点中含较大元素的节点位置 
		}
		if(arr[0]>=arr[i]){  //如果根节点比两个子节点都大,那就不需要操作 
			break;
		}
		else{    
			arr[k]=arr[i]; //否则将大的值赋给根节点,此时堆可能被破坏,需要调整 
			k=i;  //将那个子节点的位置设为下一次堆调整的堆顶 
		}
	}
	arr[k]=arr[0];  //在上面break后,将原定的根节点(原来的arr[k],现在的arr[0])的值赋给 k=i处的节点 
} 

//初始条件:将一个二维数组通过headajust函数建立成一个初始的大根堆 
//输入:一维数组arr且从第1位开始,第0位不存储数据;len堆的数字个数(因为是建立初始的堆)(不包含第0位)  
//输出:一个初始的最大大根堆 
void buildmaxheap(int arr[],int len){
	int mid;
	for(mid=len/2;mid>0;mid--){   //从含有最后一个孩子节点的 n/2处节点开始调整堆 
		headajust(arr,mid,len);    //反复调整,直至到达第1个节点 
	}
} 

//初始条件:将一个二维数组通过建立初始最大大根堆和迭代调整堆,来完成堆排序 
//输入:一维数组arr且从第1位开始,第0位不存储数据;len堆的数字个数(不包含数组第0位) 
//输出:一个完成堆排序的数组 
void heapsort(int arr[],int n){
	buildmaxheap(arr,n);
	int i,temp;
	for(i=n;i>1;i--){
		temp=arr[i];
		arr[i]=arr[1];
		arr[1]=temp;
		headajust(arr,1,i-1);
	}
} 


int main(){
	
	int arr[6]={4,9,2,0,198,3};
	int arrr[7]={0,4,9,2,0,198,3};
//	bubblesort(arr,6);
//	quicksort(arr,0,5);
//	mergesort(arr,0,5);
//	insertsort(arr,6);
//	shellsort(arr,6);
//	selectsort(arr,6);
//
//	for(int i=0;i<6;i++){
//		printf("%d\n",arr[i]);
//	}

//	heapsort(arrr,6);
//	for(int i=1;i<7;i++){
//		printf("%d\n",arrr[i]);
//	}
	
	
}

欢迎纠错、补充

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值