排序算法汇总---C++实现各个排序

排序汇总:
下图为各个排序的时空复杂度:
各个排序的时空复杂度

  1. 冒泡排序:
//冒泡排序
void bubble_sort(vector<int> &v){
	for(int i = 0;i < v.size()-1;i++){//n-1趟 
		for(int j = 0;j< v.size()-i-1;j++){//n-趟数-1 
			if(v[j] > v[j+1]){
				int temp = v[j];
				v[j] = v[j+1];
				v[j+1] = temp;
			}
		}
	}
}

2.直接插入排序:

//直接插入排序
void insert_sort(vector<int> &v){
	for(int i = 1;i < v.size();i++){
		for(int j = i;j > 0;j--){
			if(v[j] < v[j-1]){
				int temp = v[j];
				v[j] = v[j-1];
				v[j-1] = temp;
			}
		}
	}
} 
  1. 希尔排序(改进的插入排序):
//希尔排序
void shell_sort(vector<int> &v){
	//先求出间隔gap
	int h = 1;
	while(h < v.size()/3){
		h = h*3 + 1;//Knuth序列 
	} 
	for(int gap = h;gap > 0;gap = (gap-1)/3){
		//下面为插入排序
		for(int i = gap;i < v.size();i++){
			for(int j = i;j > gap-1;j-=gap){
				if(v[j] < v[j-gap]){
					int temp = v[j];
					v[j] = v[j-gap];
					v[j-gap] = temp;
				}
			}
		} 
	}
}
  1. 选择排序:
//选择排序
void select_sort(vector<int> &v){
	for(int i = 0;i < v.size()-1;i++){
		int min = i;
		for(int j = i+1;j < v.size();j++){
			if(v[j] < v[min]){
				min = j;
			}
		}
		if(min != i){
			int temp = v[min];
			v[min] = v[i];
			v[i] = temp;
		}
	}
}
  1. 快速排序:
//划分方法
int partition(vector<int> &v,int low,int high){
	int mid = low + (high-low)/2;//以中间元素作为枢轴 
	int temp = v[mid];
	v[mid] = v[low];
	v[low] = temp;
	int pivot = v[low];
	while(low < high){
		while(low < high && pivot <= v[high]){
			high--;
		}
		v[low] = v[high];
		while(low < high && v[low] <= pivot){
			low++;
		}
		v[high] = v[low];
	}
	v[low] = pivot;
	return low;
} 
 
//快速排序 
void quick_sort(vector<int> &v,int low,int high){
	if(low < high){
		int mid = partition(v,low,high);
		quick_sort(v,low,mid-1);
		quick_sort(v,mid+1,high); 
	}
}
  1. 归并排序:
//归并 
void merge(vector<int> &v,int low,int mid,int high){
	int i = low;
	int j = mid+1;
	int k = 0;
	vector<int> temp;
	temp.resize(high-low+1);
	while(i <= mid && j <= high){
		if(v[i] <= v[j]){
			temp[k++] = v[i++];
		}else{
			temp[k++] = v[j++];
		}
	}
	while(i <= mid){
		temp[k++] = v[i++];
	}
	while(j <= high){
		temp[k++] = v[j++];
	}
	for(int m = 0;m < temp.size();m++){
		v[low+m] = temp[m];
	}
}

//归并排序
void merge_sort(vector<int> &v,int low,int high){
	if(low < high){
		int mid = low + (high - low) / 2;
		merge_sort(v,low,mid);
		merge_sort(v,mid+1,high);
		merge(v,low,mid,high);
	}
} 
  1. 计数排序(桶排序的一种):
//计数排序
void count_sort(vector<int> &v){
	int max = 0;
	//找出数组中的最大值 
	for(int i = 0; i < v.size();i++){
		if(max < v[i]){
			max = v[i];
		}
	}
	//创建辅助数组
	vector<int> result;//存放最后排序结果的数组 
	result.resize(v.size());
	vector<int> count; //计数数组
	count.resize(max+1);
	//开始计数 
	for(int i = 0;i < v.size();i++){
		count[v[i]]++;
	} 
	//为了保持计数排序的稳定,需要计算累加数组
	//累加数组的好处是,可以记录原数组相同元素的最后一个位置 
	for(int i = 1;i < count.size();i++){
		count[i] = count[i] + count[i-1];
	} 
	//逆序遍历原数组,然后赋值给结果数组 
	for(int i = v.size()-1;i >=0;i--){
		int index = count[v[i]]-1;//原数组的数字的相对位置,对应结果数组的相对位置
		result[index] = v[i];
		count[v[i]]--;//因为有重复元素,所以需要减一。 
	}
	//把结果数组复制到元素组
	for(int i = 0;i < result.size();i++){
		v[i] = result[i];
	} 
} 
  1. 基数排序(桶排序的一种):
//基数排序
void radix_sort(vector<int> &v){
	int max = 0;
	//求出数组中的最大值 
	for(int i = 0;i < v.size();i++){
		if(max < v[i]){
			max = v[i];
		}
	}
	int k = 0;//最大数字的位数,即需要k个基数 
	while(max!=0){
		k++;
		int num = max % 10;//计算每一位
		max = max/10; 
	}
	vector<int> result;//结果数组 
	result.resize(v.size());
	vector<int> count;//计数数组 
	count.resize(10);//每个数字都是从0-9,故需要10个长度 
	for(int m = 0;m < k;m++){
		
		//下面为计数排序
		int division = pow(10,m);//计算每次除以的值,即1,10,100……
		//求出计数数组 
		for(int i = 0;i < v.size();i++){
			int num = v[i]/division % 10;//计算每一位 
			count[num]++; 
		} 
		//求出累加数组 
		for(int i = 1;i < count.size();i++){
			count[i] = count[i] + count[i-1];
		}
		//求出结果数组
		for(int i = v.size()-1;i >=0;i--){
			int n = v[i]/division % 10;//计算每个值当前位的数字 
			int index = count[n]-1;
			result[index] = v[i];
			count[n]--;//因为有重复的数字,所以需要减一 
		}
		for(int i = 0;i < result.size();i++){
			v[i] = result[i];
		}
		//count数组清空 
		for(int i = 0;i < count.size();i++){
			count[i] = 0;
		} 
	}
	
} 
  1. 堆排序:
//调整堆
void heapify(vector<int> &v,int len,int pos){
	if(len <= pos){
		return;
	}
	int left = pos * 2 + 1;//左结点 
	int right = pos * 2 +2;//右结点
	int max = pos;//默认当前位置为最大值
	if(left < len && v[max] < v[left]){
		max = left;
	} 
	if(right < len && v[max] < v[right]){
		max = right;
	}
	if(max != pos){
		swap(v[max],v[pos]);
		heapify(v,len,max);
	}
} 
//构建堆
void build_heap(vector<int> &v){
	int lastNode = v.size() - 1;
	int parent = (lastNode - 1) / 2;
	for(int i = parent;i >= 0;i--){
		heapify(v,v.size(),i);
	}
} 
//堆排序
void heap_sort(vector<int> &v){
	//把给定的数组构建为堆 
	build_heap(v);
	for(int i = v.size()-1;i >= 0;i--){
		swap(v[i],v[0]);//最后一个结点和根结点交换 
		heapify(v,i,0);
	}
} 

二分查找:

//二分查找,返回找到数字的下标,未找到返回-1 
int binary_search(vector<int> v,int key){//v为已经排好序的数组 
	if(v.size()==0){
		return -1;//未找到 
	}
	int low = 0;
	int high = v.size()-1;
	int mid = 0;
	while(low <= high){
		mid = (low+high)/2;
		if(v[mid]==key){
			return mid;
		}else if(v[mid] > key){
			high = mid-1;//从前半部分查找 
		}else{
			low = mid +1;//从后半部分查找 
		}
	}
	return -1;
} 
发布了102 篇原创文章 · 获赞 21 · 访问量 5万+

猜你喜欢

转载自blog.csdn.net/guanripeng/article/details/104654858