用递归的合并排序对如下数据进行排序(45, 23, 65, 57, 38, 2, 96, 87, 14, 70 )
合并排序算法是用分治策略实现对n个元素进行排序的算法;
基本思想:
将待排序数组分为成分大小大致相同的2个子集和;
分别对两个子集和进行排序;
合并两个排序后的子集和。
代码实现:(时间复杂度:O(nlongn))
#include<iostream>
using namespace std;
void merge(int a[],int start,int end,int b[])//合并
{
int leftl=(end-start+1)/2+1;
int lefti=start;
int righti=start+leftl;
int resulti=start;
while(lefti<start +leftl&&righti<end+1)
{
if(a[lefti]<=a[righti])
b[resulti++]=a[lefti++];
else
b[resulti++]=a[righti++];
}
while(lefti<start+leftl)
b[resulti++]=a[lefti++];
while(righti<end+1)
b[resulti++]=a[righti++];
}
void mergesort(int a[],int start,int end,int b[])
{
if(1==end-start)
{
if(a[start]>a[end])
{
int temp=a[start];
a[start]=a[end];
a[end]=temp;
}
return;
}
else if(0==end-start)
return;
else
{
mergesort(a,start,(end-start+1)/2+start,b);
mergesort(a,(end-start+1)/2+start+1,end,b);
merge(a,start,end,b);
for(int i = start;i <= end;++i)
a[i] = b[i];
}
}
int main()
{
int a[] = {45, 23, 65, 57, 38, 2, 96, 87, 14, 70};
const int length = 10;
int b[length];
cout << "排序前:" << endl;
for(int i = 0;i < length;++i)
cout << a[i] << " ";
cout << endl;
cout << "排序后:" << endl;
mergesort(a,0,length-1,b);
for(int i = 0;i < length;++i)
cout << a[i] << " ";
cout << endl;
return 0;
}
排列A中若存在i<j且Ai>Aj,则称<Ai, Aj>是该排列的一个逆序,一个排列含有逆序的个数称为该排列的逆序数。例如排列2 6 3 4 5 1中含有8个逆序<2, 1>、<6, 3>、<6, 4>、<6, 5>、<6, 1>、❤️, 1>、<4, 1>、<5, 1>。利用分治思想设计算法,计算给定排列的逆序数。
在合并排序的基础上加计数器计算逆序数。
#include<iostream>
using namespace std;
int count=1;//计数器
void merge(int a[],int start,int end,int b[])
{
int leftl=(end-start+1)/2+1;
int lefti=start;
int righti=start+leftl;
int resulti=start;
while(lefti<start +leftl&&righti<end+1)
{
if(a[lefti]<=a[righti])
b[resulti++]=a[lefti++];
else
{
count+=righti-resulti;//计算逆序数
b[resulti++]=a[righti++];
}
}
while(lefti<start+leftl)
b[resulti++]=a[lefti++];
while(righti<end+1)
b[resulti++]=a[righti++];
}
void mergesort(int a[],int start,int end,int b[])
{
if(1==end-start)
{
if(a[start]>a[end])
{
int temp=a[start];
a[start]=a[end];
a[end]=temp;
}
return;
}
else if(0==end-start)
return;
else
{
mergesort(a,start,(end-start+1)/2+start,b);
mergesort(a,(end-start+1)/2+start+1,end,b);
merge(a,start,end,b);
for(int i = start;i <= end;++i)
a[i] = b[i];
}
}
int main()
{
int a[] = {2, 6, 3, 4, 5,1};
const int length = 6;
int b[length];
cout << "排序前:" << endl;
for(int i = 0;i < length;++i)
cout << a[i] << " ";
cout << endl;
cout << "排序后:" << endl;
mergesort(a,0,length-1,b);
for(int i = 0;i < length;++i)
cout << a[i] << " ";
cout<<endl;
cout <<"逆序数:" <<count<<endl;
return 0;
}
设A 是n个数构成的数组,其中出现次数最多的数称为众数,设计一个算法求A的众数。
首先对数组进行排序,及在合并排序的基础上求众数。
对数组进行遍历,求出数量最多的那个数。
//添加上合并排序的代码段
void most(int a[],int length)
{
int i = 0;
int MaxCount = 1;
int index = 0;
while (i < length - 1)
{
int count = 1;
int j ;
for (j = i; j < length - 1; j++)
{
if (a[j] == a[j + 1]) count++;
else break;
}
if (MaxCount < count)
{
MaxCount = count;
index = j;
}
++j;
i = j;
}
cout <<"众数:" <<a[index] << " 出现次数:" << MaxCount << endl;
}