常用排序

//交换值

void swap(int *ps,int *pt){
	int data = *ps;
	*ps = *pt;
	*pt = data;
}

//1.堆排序

void reheap(int arr[],size_t index,size_t len){
	int data = arr[index];
	int child = 0;
	for(;index<len;index=child){
		child = 2*index+1;
		if(child>=len){
			break;	
		}
		if(child+1<len && arr[child]<arr[child+1]){
			++child;	
		}
		
		if(data < arr[child]){
			arr[index] = arr[child];	
		}else{
			break;	
		}
	}
	arr[index] = data;
}

void heap(int arr[],size_t len){
	for(int i = len/2-1;i>=0;--i){
		reheap(arr,i,len);
	}
}

void heapSort(int arr[],size_t len){
	heap(arr,len);
	for(int i=len-1;i>0;--i){
		swap(&arr[0],&arr[i]);
		reheap(arr,0,i);
	}
}

//2.冒泡排序

void bubbleSort(int arr[],size_t len){
	for(int i=0;i<len-1;i++){
		bool isSwap = false;
		for(int j=1;j<len-i;j++){
			if(arr[j]<arr[j-1]){
				swap(&arr[j],&arr[j-1]);
				isSwap = true;
			}	
		}	
		if(!isSwap){
			break;	
		}
	}	
}

//3.选择排序

void selectSort(int arr[],size_t len){
	for(int i=0;i<len-1;i++){
		int maxInd = 0;
		for(int j=1;j<len-i;j++){
			if(arr[maxInd] < arr[j]){
				maxInd = j;	
			}
		}
		if(maxInd != len-1-i)
			swap(&arr[maxInd],&arr[len-1-i]);
	}
	
}

//4.鸡尾酒排序

void cookSort(int arr[],size_t len){
	for(int i=0;i<len/2;i++){
		int minInd = i;
		int maxInd = i;
		for(int j=i+1;j<len-i;j++){
			if(arr[j]<arr[minInd]){
				minInd = j;	
			}	
			if(arr[maxInd]<arr[j]){
				maxInd = j;	
			}
		}
		if(minInd != i){
			swap(&arr[minInd],&arr[i]);	
		}
		if(maxInd == i){
			maxInd = minInd;	
		}
		if(maxInd != len-1-i){
			swap(&arr[maxInd],&arr[len-1-i]);	
		}
	}	
}

//5.插入排序

void insertSort(int arr[],size_t len){
	for(int i=1;i<len;i++){//把arr[i]插入到前面,使用arr[0..i]区间都有序
		int j=i-1;
		int data = arr[i];
		for(;j>=0&&data < arr[j];--j){
			arr[j+1] = arr[j];
		}
		arr[j+1] = data;
	}	
}

//6.二分插入排序

void binSort(int arr[],size_t len){
	for(int i=1;i<len;i++){
		int left = 0;
		int right = i-1;
		int data = arr[i];
		while(left<=right){
			int mid = (left+right)/2;
			if(data<arr[mid]){
				right = mid-1;
			}else{
				left = mid+1;	
			}
		}
		int j = i-1;
		for(;j>right;--j){
			arr[j+1] = arr[j];	
		}	
		arr[j+1] = data;
	}	
}

//7.希尔排序

void shellSort(int arr[],size_t len){
	for(int step = len/2;step>0;step = step/2){//分组
		for(int j = step;j<len;j++){
			int data = arr[j];
			int k = j-step;
			for(;k>=0&&data<arr[k];k-=step){
				arr[k+step] = arr[k];	
			}
			arr[k+step] = data;
		}	
	}
}

//8.归并排序

void mergerArr(int arr[],size_t left,size_t right){
	int mid = (left+right)/2;  //[left,mid]  [mid+1,right]分别是有序的
	//合并  [left,right]区间有序
	int lds = mid+1-left;
	int *pd = malloc(lds*sizeof(int));
	for(int i=0;i<lds;i++){
		pd[i] = arr[left+i];	
	}
	int i = 0,j = mid+1;//i记录pa的下标  j记录arr[mid+1,right]下标
	int k = left;
	while(i<lds && j<=right){
		if(pd[i] < arr[j]){
			arr[k++] = pd[i++];	
		}else{
			arr[k++] = arr[j++];	
		}
	}
	while(i<lds){
		arr[k++] = pd[i++];	
	}
	free(pd);
	/*不需要
	while(j<=right){
		arr[k++] = arr[j++];	
	}
	*/
}
//递归调用
void merger(int arr[],size_t left,size_t right){
	if(left>=right){
		return;	
	}
	int mid = (left+right)/2;
	if(mid-left>=1)
		merger(arr,left,mid);//对[left,mid]区间进行排序
	if(right-mid-1>=1)
		merger(arr,mid+1,right);//对[mid+1,right]区间进行排序
	mergerArr(arr,left,right);//把[left,mid],[mid+1,right]两部分有序的合并成一个整体有序的
}

void mergerSort(int arr[],size_t len){
	merger(arr,0,len-1);	
}

//9.快速排序

void quick(int arr[],int left,int right){
	int data = arr[left];
	int i = left;
	int j = right;
	while(i<j){
		while(i<j&&data<=arr[j]){--j;}
		if(i<j)
			arr[i] = arr[j];
		while(i<j&&arr[i]<=data){++i;}
		if(i<j)
			arr[j] = arr[i];
	}
	arr[i] = data;
	if(i-left>1){
		quick(arr,left,i-1);	
	}
	if(right-i>1){
		quick(arr,i+1,right);	
	}
}

void quickSort(int arr[],size_t len){
	quick(arr,0,len-1);	
}

//10.计数排序(桶排序)

void countSort(int arr[],size_t len){
	int max = arr[0];
	int min = arr[0];
	for(int i=0;i<len;i++){
		if(max < arr[i]){
			max = arr[i];	
		}	
		if(min > arr[i]){
			min = arr[i];
		}
	}
	int cnt = max+1-min;//最大值和最小值之间相差多少个数
	int *pCnt = calloc(cnt, sizeof(int));//pCnt[0]  pCnt[cnt-1]
	//pCnt[0] == 0 代表 min这个数个数为0
	//pCnt[0] == 1 代表 min这个数有一个
	//pCnt[i] == n 代表 min+i 这个数有 n 个
	for(int i=0;i<len;i++){//arr[i]这个值   pCnt[arr[i]-min]
		pCnt[arr[i]-min]++;	//arr[i]这个值的个数加1
	}
	int j = 0;
	for(int i=0;i<cnt;i++){
		while(pCnt[i] != 0){
			arr[j++] = i+min;
			--pCnt[i];
		}
	}
	free(pCnt);
}
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值