时间复杂度;
对输入规模n=5,求最小值;
int tmp=sz[0], sz[5]={1,2,3,5,4};
for(int i=0;i<5;i++){tmp>sz[i]?tmp=sz[i]:tmp;}
对于数组的每个元素进行一次比较,共计5次比较,顾其时间复杂度为O(5);
该算法的时间复杂度是O(n)
空间复杂度;
上述算法的空间复杂度是O(1);
因为他只开辟了一个元素的空间;
这段内容转载于(逍遥埠)
递归相关的空间
递归相关的空间就是由递归直接造成的内存开销,也就是跟踪函数调用的栈。
为了完成一个典型的函数调用,系统会在栈中分配一些空间来保存三类重要的信息。
•1、函数调用的返回地址。一旦函数的调用完成,程序必须要知道应该返回到哪里,也就是函数调用后的代码行。
•2、被传递给函数调用的参数。
•3、函数调用中的本地变量。
非递归相关的空间
顾名思义,非递归相关空间是指与递归不直接相关的内存空间,通常指的是用来分配全局变量的堆空间。
不管递归与否,你都应该在任何的后续函数调用之前把问题的输入作为全局变量存储起来。你同样也应该把递归调用的中间结果存储起来。后者就是我们通常所说的备忘录,优化算法的技术。
这个比较好理解,比如我们比较熟悉的斐波那契函数问题,我们用一个哈希表来记录所有在递归调用中出现的中间斐波那契数。
所以,在空间复杂度分析中,我们也一定要把由于备忘录技术所引起的内存消耗考虑在内。
以下代码为二路归并代码
#include <stdio.h>
#include<malloc.h>
void rldg(int* p, int low, int hight);
void dg(int* p, int low, int mid, int hight);
#define len (sizeof(sz)/sizeof(sz[0])-1)
int main()
{
int sz[] = { 4,2,3,1 ,5,25,11,-11,5,4,98};
int* p = sz;
rldg(p, 0, len);
for (int i = 0; i <=len; i++) { printf("%d ", sz[i]); }
}
void rldg(int* p, int low, int hight)
{
if (low < hight)
{
int mid = (low + hight) / 2;
rldg(p, low, mid);
rldg(p, mid + 1, hight);
dg(p, low, mid, hight);
}
}
void dg(int* p, int low, int mid, int hight)
{
int* pl, i = low, j = mid+1,con=0;
pl = (int*)malloc((hight - low + 1) * sizeof(int));
while ((i <= mid) && (j <= hight))
{
pl[con++] = (p[i] > p[j] ? p[j++] : p[i++]);
}
while (i <= mid) { pl[con++] = p[i++]; }
while (j <= hight) { pl[con++] = p[j++]; }
int k = low;
int kl = 0;
while (k <= hight) { p[k++] = pl[kl++]; }
free(pl);
}
#include<malloc.h>
void rldg(int* p, int low, int hight);
void dg(int* p, int low, int mid, int hight);
#define len (sizeof(sz)/sizeof(sz[0])-1)
int main()
{
int sz[] = { 4,2,3,1 ,5,25,11,-11,5,4,98};
int* p = sz;
rldg(p, 0, len);
for (int i = 0; i <=len; i++) { printf("%d ", sz[i]); }
}
void rldg(int* p, int low, int hight)
{
if (low < hight)
{
int mid = (low + hight) / 2;
rldg(p, low, mid);
rldg(p, mid + 1, hight);
dg(p, low, mid, hight);
}
}
void dg(int* p, int low, int mid, int hight)
{
int* pl, i = low, j = mid+1,con=0;
pl = (int*)malloc((hight - low + 1) * sizeof(int));
while ((i <= mid) && (j <= hight))
{
pl[con++] = (p[i] > p[j] ? p[j++] : p[i++]);
}
while (i <= mid) { pl[con++] = p[i++]; }
while (j <= hight) { pl[con++] = p[j++]; }
int k = low;
int kl = 0;
while (k <= hight) { p[k++] = pl[kl++]; }
free(pl);
}
------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
时间复杂度 O(n*logn)递归深度logn,每一层递归是对n个元素进行操作。
空间复杂度O(n)+--------------{大约2*(元素个数)*(4+4*4+4*4} (该部分是低阶常量,忽略) ----------------;
------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
下面是直接插入
#define _CRT_SECURE_NO_WARNINGS
#include<stdio.h>
int main()
{
int sz[] = { 10,9,8,-7,1,5,4,3,-2,6, };
int len = sizeof(sz) / sizeof(sz[0]);
for (int i = 1; i < len; i++)
{
for (int j = 0; j < i; j++)
{
if (sz[i] < sz[j])
{
int tem = sz[i];
for(int k=i;k>j;k--)
{
sz[k] = sz[k - 1];
}
sz[j] = tem;
break;
}
}
}
for (int i = 0; i < len; i++)
{
printf("%d ", sz[i]);
}
#include<stdio.h>
int main()
{
int sz[] = { 10,9,8,-7,1,5,4,3,-2,6, };
int len = sizeof(sz) / sizeof(sz[0]);
for (int i = 1; i < len; i++)
{
for (int j = 0; j < i; j++)
{
if (sz[i] < sz[j])
{
int tem = sz[i];
for(int k=i;k>j;k--)
{
sz[k] = sz[k - 1];
}
sz[j] = tem;
break;
}
}
}
for (int i = 0; i < len; i++)
{
printf("%d ", sz[i]);
}
}
------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
时间复杂度 大约是O(n*(n--1)/2)=O(n^2*0.5)=O(n^2)(去掉低阶常量)
空间复杂度O(1)只需开辟一个tem空间(1)
------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
总结
小规模用插入排序(节约空间)
大规模用归并(牺牲空间,速度更快)