排序汇总:
下图为各个排序的时空复杂度:
- 冒泡排序:
//冒泡排序
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;
}
}
}
}
- 希尔排序(改进的插入排序):
//希尔排序
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;
}
}
}
}
}
- 选择排序:
//选择排序
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;
}
}
}
- 快速排序:
//划分方法
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);
}
}
- 归并排序:
//归并
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);
}
}
- 计数排序(桶排序的一种):
//计数排序
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];
}
}
- 基数排序(桶排序的一种):
//基数排序
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;
}
}
}
- 堆排序:
//调整堆
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;
}