一,算法的大O表示法(时间复杂度,空间复杂度 是从内存的计算的)
1,算法效率严重依赖于操作(operation)数量
2,在判断时首先关注操作数量的最高次项
3,操作数量的估值可以作为时间复杂度的估算
2n + 3 O(n) 线性阶
3n^2 + 2n + 1 O(n^2) 平方阶
5log2n + 20 O(logn) 对数阶
2n + 3nlog2n + 19 O(nlogn) nlogn阶
6n^3 + 2n^2 + 3n + 4 O(n^3) 立方阶
2^n O(2^n) 指数阶
下面是对操作数复杂度推
O(5) = O(1)
O(2n + 1) = O(2n) = O(n)
O(n^2 + n + 1) = O(n^2)
O(3 * n^3 + 1) = O(3 n^3) = O(n^3)
关系:
O(1) < O(logn) < O(nlogn) < O(n^2) < O(n^3) < O(n^2) < O(n^n)
1,算法是最终要编译成具体的计算机指令
2,每一个指令 在具体的计算机 cpu 上运行的时间是固定的
3,通过具体的n的步骤的多少就可以推算法的复杂度
n->无穷大时 可以忽略 + 4了 就是 O(n)
下面是一个例子:
long sum1(int n) // 2n + 4 ===> n->无穷大时 可以忽略 + 4了 就是 O(n)
{
long ret = 0; //1
int* array = (int*)malloc(sizeof(int)* n); //1
int i;// 1
for (i = 0; i < n; i++) //n
array[i] = i + 1;
for (i = 0; i < n; i++) //n
ret += array[i];
free(array); //1
return ret;
}
long sum2(int n) //n + 2 ===> n->无穷大 是 O(n)
{
long ret = 0; // 1
int i = 0; // 1
for (i = 1; i <= n; i++) // n
ret += i;
return ret;
}
long sum3(int n) // 2 ==== 》 O(1)
{
long ret = 0; // 1
if (n > 0)
{
ret = (1 + n) * n / 2; // 1 // 2
}
return ret;
}
二,二叉树的性质
1,性质1:在二叉树的第i层上至多有 n^2-1 个结点(i > 0)
2,性质2:深度为k的二叉树至多有2^k - 1 个结点 (k > 0)
3,性质3:对于任何一颗二叉树,若2度的结点树有n2个,则叶子数(n0)必定为n2 + 1 (即n0 = n2 + 1)
4,性质4:具有n个结点的 具有n个结点的完全二叉树的深度必为log2n+1
(如 log2 (15) 点击 15 log / 2 log =)
5, 性质5: 对完全二叉树,若从上至下、从左至右编号,则编号为i 的结点,其左孩子编号必为2i,其右孩子编号必为2i+1;其双亲的编号必为i/2(i=1 时为根,除外)
三,二叉树遍历
1, DLR 先序遍历,即先根 再左 再右
2, LDR — 中序遍历,即先左 再根 再右
3, LRD — 后序遍历,即先左 再右 再根
1,求二叉树的叶子数
分析图
判断树的下面有没有孩子如果两个right孩子和left孩子都没有就是叶子
void calcteleafNum(struct Binarytree* root, int* p)
{
//判断数是否为空返回
if (root == NULL)
return NULL;
if (root->lchild == NULL && root->rchild == NULL)
(*p)++;
calcteleafNum(root->rchild, p);
calcteleafNum(root->lchild, p);
}
2,求二叉树的深度
分析图
判断树最下的树的判断大小加1
int getTree(struct Binarytree* root)
{
//判断数是否为空返回
if (root == NULL)
return NULL;
//ringth tree的深度
int rlength = getTree(root->rchild);
int llength = getTree(root->lchild);
int Heigth = rlength > llength ? rlength + 1 : llength + 1;
return Heigth;
}
3,二叉树的拷贝
分析图
先拷贝出right孩子和left孩子在开辟内存保存信息
struct Binarytree* copyTree(struct Binarytree* root)
{
if (!root) return NULL;
struct Binarytree* rChild = copyTree(root->rchild);
struct Binarytree* lChild = copyTree(root->lchild);
struct Binarytree* newTree = (struct Binarytree*)malloc(sizeof(struct Binarytree));
newTree->rchild = rChild;
newTree->lchild = lChild;
newTree->ch = root->ch;
return newTree;
}