归并排序
- 归并算法非递归实现
- 归并算法应用
- 抢气球问题
归并算法采用的是分治的思想,是不断将一个序列一分为二,最后合并进行排序的一个过程。
在下面的代码中,mergePass函数起的作用就是“分”,而merge_array函数的作用是“治”和“合”。
最后在主函数中通过循环的方法实现了非递归实现。
时间复杂度是O(nlogn),排序稳定
归并算法非递归实现
// An highlighted block
#include<iostream>
using namespace std;
int test1[100000];
int test2[100000];
void merge_array(int *c,int *d,int l,int m,int r);
void mergePass(int *c,int *d,int s,int length_t);
int main(void){
int length_t;
int s = 1;
cin>>length_t;
int i=0;
for(;i<length_t;i++)
cin>>test1[i];
while(s<length_t){
mergePass(test1,test2,s,length_t);
s+=s;
mergePass(test2,test1,s,length_t);
s+=s;
}
for(int k=0;k<length_t;k++)
cout<<test1[k]<<" ";
}
void mergePass(int *c,int *d,int s,int length_t){//将c数组分别排序并合并到d数组
int i=0;
while(i<=(length_t-2*s)){
merge_array(c,d,i,i+s-1,i+2*s-1);
i=i+2*s;
}
if(i+s<length_t){//剩下部分大于s
merge_array(c,d,i,i+s-1,length_t-1);
}//剩下的部分小于2s,分为大于s或者小于等于s
else{
for(int j=i;j<length_t;j++)
d[j]=c[j];
}//小于等于s
}
void merge_array(int *c,int *d,int l,int m,int r){//将数组c合并到d数组中,可以合并了,然后接下来就是分割战场
int i=l;
int j=m+1;
int k=l;
while(i<=m&&j<=r){
if(c[i]<=c[j])
d[k++]=c[i++];
else
d[k++]=c[j++];
}
if(i>m){
while(j<=r)
d[k++]=c[j++];
}
else{
while(i<=m)
d[k++]=c[i++];
}
}
归并算法应用
如题:进行两次排序
// An highlighted block
#include<iostream>
using namespace std;
int test1[10000];
int test2[10000];
int test3[10000];
void merge_array1(int *c,int *d,int l,int m,int r);
void mergePass1(int *c,int *d,int s,int l,int r);
void merge_array2(int *c,int *d,int l,int m,int r);
void mergePass2(int *c,int *d,int s,int l,int r);
int main(void){
int length_t;
int s = 1;
cin>>length_t;
int l1,r1,l2,r2;
cin>>l1>>r1>>l2>>r2;
int i=0;
for(;i<length_t;i++){
cin>>test1[i];
}
while(s<r1-l1+1){
mergePass1(test1,test2,s,l1-1,r1-1);
s+=s;
mergePass1(test2,test1,s,l1-1,r1-1);
s+=s;
}
s=1;
while(s<r2-l2+1){
mergePass2(test1,test3,s,l2-1,r2-1);
s+=s;
mergePass2(test3,test1,s,l2-1,r2-1);
s+=s;
}
for(int k=0;k<length_t;k++)
cout<<test1[k]<<" ";
}
void mergePass1(int *c,int *d,int s,int l,int r){//修改一下,这里不写长度,这里写数组下标
int i=l;//i为起始的下标
while(i<=(r+1-2*s)){//长度和r下标的区别
merge_array1(c,d,i,i+s-1,i+2*s-1);
i=i+2*s;
}
if(i+s<r+1){//剩下部分大于s
merge_array1(c,d,i,i+s-1,r);
}//剩下的部分小于2s,分为大于s或者小于等于s
else{
for(int j=i;j<r+1;j++)
d[j]=c[j];
}//小于等于s
}
void merge_array1(int *c,int *d,int l,int m,int r){//将数组c合并到d数组中,可以合并了,然后接下来就是分割战场
int i=l;
int j=m+1;
int k=l;
while(i<=m&&j<=r){
if(c[i]<=c[j])
d[k++]=c[i++];
else
d[k++]=c[j++];
}
if(i>m){
while(j<=r)
d[k++]=c[j++];
}
else{
while(i<=m)
d[k++]=c[i++];
}
}
void mergePass2(int *c,int *d,int s,int l,int r){//修改一下,这里不写长度,这里写数组下标
int i=l;//i为起始的下标
while(i<=(r+1-2*s)){//长度和r下标的区别
merge_array2(c,d,i,i+s-1,i+2*s-1);
i=i+2*s;
}
if(i+s<r+1){//剩下部分大于s
merge_array2(c,d,i,i+s-1,r);
}//剩下的部分小于2s,分为大于s或者小于等于s
else{
for(int j=i;j<r+1;j++)
d[j]=c[j];
}//小于等于s
}
void merge_array2(int *c,int *d,int l,int m,int r){//将数组c合并到d数组中,可以合并了,然后接下来就是分割战场
int i=l;
int j=m+1;
int k=l;
while(i<=m&&j<=r){
if(c[i]>c[j])
d[k++]=c[i++];
else
d[k++]=c[j++];
}
if(i>m){
while(j<=r)
d[k++]=c[j++];
}
else{
while(i<=m)
d[k++]=c[i++];
}
}
抢气球问题
#include<iostream>
using namespace std;
long airball[100000];//气球高度
long a[100000];
int getRank[100000];//相应的小朋友排名映射。初始标号到排名的映射
long height[100000];//小朋友跳的高度
long origin[100000];
void mergePass(long *c,long *d,int length,int s);
void merge_array(long *c,long *d,int l,int m,int r);
int main(void){
int n,m;
cin>>n>>m;//n是小朋友的数量,m是气球的数量
int i=0;
for(;i<n;i++){
cin>>height[i];
}
for(i=0;i<m;i++)
cin>>airball[i];//气球高度就直接归并排序吧
int s=1;
while(s<m){
mergePass(airball,a,m,s);
s+=s;
mergePass(a,airball,m,s);
s+=s;
}//气球序列排好了
//选择排序进行操作吧
for(i=0;i<n;i++)
getRank[i]=i;
int minh=0;
int k=0;
int j=0;
long temp1=0;
int temp2=0;
for(;k<n-1;++k){
minh=k;
for(j=k+1;j<n;j++){
if(height[j]<height[minh]){
minh=j;
}
}
temp1=height[k];
height[k]=height[minh];
height[minh]=temp1;
temp2=getRank[k];
getRank[k]=getRank[minh];
getRank[minh]=temp2;
}
//归并排序出了一点错
//依次输出吧,temp1作为临时变量存储数据
j=0;
for(i=0;i<n;++i){
temp1=0;
if(j<m){
for(;height[i]>=airball[j];j++)
temp1++;
origin[getRank[i]]=temp1;
}
else
origin[getRank[i]]=0;
}
for(i=0;i<n-1;i++)
cout<<origin[i]<<endl;
cout<<origin[n-1];
}
//归并排序
void mergePass(long *c,long *d,int length_t,int s){//将c数组分别排序并合并到d数组
int i=0;
while(i<=(length_t-2*s)){
merge_array(c,d,i,i+s-1,i+2*s-1);
i=i+2*s;
}
if(i+s<length_t){//剩下部分大于s
merge_array(c,d,i,i+s-1,length_t-1);
}//剩下的部分小于2s,分为大于s或者小于等于s
else{
for(int j=i;j<length_t;j++)
d[j]=c[j];
}//小于等于s
}
void merge_array(long *c,long *d,int l,int m,int r){//将数组c合并到d数组中,可以合并了,然后接下来就是分割战场
int i=l;
int j=m+1;
int k=l;
while(i<=m&&j<=r){
if(c[i]<=c[j])
d[k++]=c[i++];
else
d[k++]=c[j++];
}
if(i>m){
while(j<=r)
d[k++]=c[j++];
}
else{
while(i<=m)
d[k++]=c[i++];
}
}