各种内部排序(一)

直接插入排序

void insert_sort(int arr[],size_t n){
	int i,j;
	//第一个元素前面没有元素,所以不需要插入,一个元素肯定是有序 
	for(i=1;i<n;++i){//把元素arr[i]往前插入 [0,i-1]区间有序  使得  [0,i]区间有序 
		int key = arr[i];         //记录需要插入的元素arr[i];
		for(j=i-1;j>=0&&key<arr[j];--j){//key比arr[j]要小 说明key要放到arr[j]的前面  arr[j]要往后移 
			arr[j+1] = arr[j];
		} 
		if(j+1 != i){//如果 j+1 == i     arr[j+1]本来存储的就是key 
			arr[j+1] = key;
		} 
	}
}

折半插入排序

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

二路插入排序

void two_road_insert_sort(int arr[],size_t n){
	//需要把arr中的元素使用二分插入到brr数组中 
	int brr[n];
	int max=0,min = 0;//记录brr数组中最大值和最小值的下标 
	brr[0] = arr[0];  //brr中只有一个值   brr[0] 
	int i,j;
	for(i=1;i<n;++i){//把arr中所有元素逐一插入到brr数组中 
		//arr[i]
		if(arr[i]>=brr[max]){//插入的元素大于等于brr中最大值元素  max后面 
			brr[++max] = arr[i];
		}else if(arr[i]<=brr[min]){//插入的元素小于等于brr中最小值  min前面 
			//min = (min-1+(int)n)%n;
			if(min==0){
				min = n-1;
			}else{
				--min;
			}
			brr[min] = arr[i];
		}else if(arr[i]>brr[0]){
			for(j=max;j>=0&&brr[j]>arr[i];--j){//把大于arr[i]往后移 
				brr[j+1] = brr[j];
			}
			++max;
			brr[j+1] = arr[i];
		}else{
			for(j=min;j<n&&brr[j]<arr[i];++j){//把小于arr[i]往前移 
				brr[j-1] = brr[j];
			}
			--min;
			brr[j-1] = arr[i];
		}
	}
	
	for(i=0;i<n;i++){
		arr[i] = brr[(i+min)%n];    //利用求余 可以找到min前面的数
	}
}

希尔排序

void shell_insert_sort(int arr[],size_t n){
	int step,i,j;
	for(step=n/2;step>0;step=step/2){
		for(i=step;i<n;++i){//从组内第二个元素开始进行组内插入
			int key = arr[i];
			//组内插入  i  i-step前一个元素 
			for(j=i-step;j>=0&&key<arr[j];j=j-step){
				arr[j+step] = arr[j];
			} 
			if(j+step!=i){
				arr[j+step] = key;
			}
		}
	}
}

简单选择排序

void select_sort(int arr[],size_t n){
	int i,j;
	for(i=1;i<n;++i){
		//循环[0,n-i]区间  记录最大值的下标
		int index = 0;      
		for(j=1;j<=n-i;++j){//循环指定的区间 记录最大值的下标 
			if(arr[index] < arr[j]){
				index = j;
			}
		}
		if(index != n-i){
			int tmp = arr[index];
			arr[index] = arr[n-i];
			arr[n-i] = tmp;
		}
	}
}

堆排序

void reheap(int arr[],int pos,size_t n){
	int key = arr[pos];
	int child = 2*pos + 1;  //pos左孩子下标
	while(child<n){//左孩子存在 
		if(child+1<n && arr[child]<arr[child+1]){//右孩子存在且右孩子大 
			++child; 
		}
		if(key < arr[child]){
			arr[pos] = arr[child];
			pos = child;
			child = 2*pos + 1;
		}else{
			break; 
		}
	} 
	arr[pos] = key;
}

void heap_sort(int arr[],size_t n){
	int i;
	//把arr调整为大根堆 
	for(i=n/2-1;i>=0;--i){
		reheap(arr,i,n); 
	}	
	for(i=n-1;i>0;--i){
		//把arr[0]和最后一个元素交换位置 
		int tmp = arr[0];
		arr[0] = arr[i];
		arr[i] = tmp;
		//0下标元素发生改变  只需要重新调整0位置的元素即可 
		reheap(arr,0,i);
	}
}

冒泡排序

//如果数组有序   时间复杂度为O(n)    平均时间复杂度O(n^2) 
void bubble_sort(int arr[],size_t n){
	int i,j;
	for(i=0;i<n;++i){
		bool swap = false;
		for(j=1;j<n-i;++j){
			//arr[j-1]  arr[j]
			if(arr[j] < arr[j-1]){
				int tmp = arr[j];
				arr[j] = arr[j-1];
				arr[j-1] = tmp;
				swap = true;
			}
		}
		if(!swap){//在完整的一次冒泡过程中,没有任何两个元素的值发生交换  说明有序 
			break;
		}
	}
}

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值