递归的时间复杂度的估算方法,对数器和归并排序,小和问题
这是递归的时间复杂度的估算公式,从这个公式推到,我们可以知道归并排序的时间复杂度是NlogN
具体是这样的,假设要排序的数组的个数,有N个。假设整个数组所需的T(N), 因为递归是拆分为两部分,所以它为2T(N/2),
拆分完之后,两边排序好之后,还需要排序好需要O(N)的时间复杂度。结果就是T(N) = 2* T(N/2) + O(N)。
由公式得知, a=2, b=2, d=1,
所以复杂度应该是第二个,O(N logN)
对数器
#include<iostream>
#include<ctime>
#include<cmath>
using namespace std;
void Myswap(int arr1, int arr2);
//写一个绝对正确率,但时间复杂度比较高的算法
void MySort(int arr[], int length)
{
int min = 0;
for (int i = 0; i < length; i++)
{
min = i;
for (int j = 0; j < length; j++)
{
if (arr[i]>arr[j])
{
min = j;
}
}
if (min != i)
{
Myswap(arr[min],arr[i]);
}
}
}
void Myswap(int arr1, int arr2)
{
int temp = arr1;
arr1 = arr2;
arr2 = temp;
}
void compartor(int *arr,int length)
{
MySort(arr, length);
}
//写一个归并排序,用计数器来验证
int merge(int arr[], int leftStart, int leftEnd,int rightStart,int rightEnd, int *temp)
{
int i = 0;
int start = leftStart;
int res = 0;
while (leftStart <= leftEnd&&rightStart <= rightEnd)
{
res += arr[leftStart] < arr[rightStart] ? (rightEnd - rightStart + 1)*arr[leftStart] : 0;
temp[i++] = arr[leftStart] < arr[rightStart] ? arr[leftStart++] : arr[rightStart++];
}
while (leftStart <= leftEnd)
{
temp[i++] = arr[leftStart++];
}
while (rightStart <= rightEnd)
{
temp[i++] = arr[rightStart++];
}
for (int j = 0; j < i ; j++)
{
arr[start + j] = temp[j];
}
return res;
}
int *generateRandomarray(int Maxsize,int Maxvalue)
{
int size = (int)((Maxsize + 1)*(rand() % 10 / 10.0)) - ((int)(Maxsize + 1)*(rand() % 10 / 10.0));
int *p = new int[Maxsize];
int lenth = sizeof(p) / sizeof(int);
for (int i = 0; i < lenth; i++)
{
p[i] = (int)((Maxvalue+1)*(rand()%10/10.0))-((int)(Maxvalue+1)*(rand()%10/10.0));
}
return p;
}
int *copyArray(int *arr,int length)
{
if (arr == NULL)
return NULL;
int *ptemp = new int[length];
for (int i = 0; i < length; i++)
{
ptemp[i] = arr[i];
}
return ptemp;
}
int Divide(int arr[],int L,int R,int *temp)
{
if (arr == NULL)
return 0;
if (L == R)
return 0;
int mid = L + ((R - L)>>1); //好处,避免L+R的和数据过大,导致溢出,而且位运算的速度比算术运算符快
return Divide(arr,L,mid,temp)+Divide(arr, mid+1, R, temp)+merge(arr,L,mid,mid+1,R,temp);
}
bool isEqual(int *arr1, int *arr2,int length)
{
bool flag = true;
if (arr1 == NULL&&arr2 != NULL)
{
flag = false;
goto END;
}
if (arr1 != NULL&&arr2 == NULL)
{
flag = false;
goto END;
}
if (arr1 == NULL&&arr2 == NULL)
{
goto END;
}
for (int i = 0; i < length; i++)
{
if (arr1[i] != arr2[i])
{
flag = false;
break;
}
}
END:
return flag;
}
int main(void)
{
srand((unsigned int)time);
int arr[] = { 4, 1, 5, 7, 2, 8 };
int length = sizeof(arr) / sizeof(arr[0]);
int *temp = new int[length];
memset(temp, 0, length);
int num=Divide(arr,0,length-1,temp);
cout << "小和:" <<num<< endl;
cout << "归并排序后的结果:";
for (int i = 0; i < length; i++)
{
cout << arr[i] << " ";
}
cout << endl;
cout << "----------对数器------------"<<endl;
int testTime = 500000;
int maxSize = 100;
int maxValue = 100;
bool succeed = true;
for (int i = 0; i < testTime; i++)
{
int *arr1 = generateRandomarray(maxSize, maxValue);
int length = sizeof(arr1) / sizeof(int);
int *arr2 = copyArray(arr1, length);
int temp[100] = { 0 };
Divide(arr2,0,length-1,temp);
compartor(arr1,length);
if (!isEqual(arr1, arr2,length))
{
succeed = false;
break;
}
delete[] arr1;
}
if (succeed)
{
cout << "Nice";
}
delete[] temp;
system("pause");
return 0;
}