脏数据php 脏数据的表现形式有哪些?( 五 )


3)动态内存分配需要指针或引用数据类型的支持,而静态内存分配不需要;
4)静态内存分配是按计划分配,在编译前确定内存块的大小 , 动态内存分配运行时按需分配 。
5)静态分配内存是把内存的控制权交给了编译器 , 动态内存把内存的控制权交给了程序员;
6)静态分配内存的运行效率要比动态分配内存的效率要高,因为动态内存分配与释放需要额外的开销;动态内存管理水平严重依赖于程序员的水平,处理不当容易造成内存泄漏 。
7. 头文件中的 ifndef/define/endif 干什么用?
预处理 , 防止头文件被重复使用,包括pragma once都是这样的
8. 宏定义求两个元素的最小值
#define MIN(A,B) ((A) next;
}
else
{
return NULL;
}
}
Node* pFind = pHead;
while (pCurrent) {
pFind = pFind-next;
pCurrent = pCurrent-next;
}
return pFind;
}
2. 给定一个单向链表(长度未知),请遍历一次就找到中间的指针,假设该链表存储在只读存储器 , 不能被修改
设置两个指针 , 一个每次移动两个位置,一个每次移动一个位置,当第一个指针到达尾节点时,第二个指针就达到了中间节点的位置
处理链表问题时,”快行指针“是一种很常见的技巧 , 快行指针指的是同时用两个指针来迭代访问链表,只不过其中一个比另一个超前一些 。快指针往往先行几步,或与慢指针相差固定的步数 。
node *create() {
node *p1, *p2, *head;
int cycle = 1, x;
head = (node*)malloc(sizeof(node));
p1 = head;
while (cycle)
{
coutx;
if (x != 0)
{
p2 = (node*)malloc(sizeof(node));
p2-data = https://www.04ip.com/post/x;
p1-next = p2;
p1 = p2;
}
else
{
cycle = 0;
}
}
head = head-next;
p1-next = NULL;
return head;
}
void findmid(node* head) {
node *p1, *p2, *mid;
p1 = head;
p2 = head;
while (p1-next-next != NULL)
{
p1 = p1-next-next;
p2 = p2-next;
mid = p2;
}
}
3. 将一个数组生成二叉排序树
排序,选数组中间的一个元素作为根节点,左边的元素构造左子树,右边的节点构造有子树 。
4. 查找数组中第k大的数字?
因为快排每次将数组划分为两组加一个枢纽元素,每一趟划分你只需要将k与枢纽元素的下标进行比较,如果比枢纽元素下标大就从右边的子数组中找,如果比枢纽元素下标小从左边的子数组中找,如果一样则就是枢纽元素,找到,如果需要从左边或者右边的子数组中再查找的话,只需要递归一边查找即可,无需像快排一样两边都需要递归,所以复杂度必然降低 。
最差情况如下:假设快排每次都平均划分,但是都不在枢纽元素上找到第k大第一趟快排没找到 , 时间复杂度为O(n),第二趟也没找到,时间复杂度为O(n/2),第k趟找到,时间复杂度为O(n/2k),所以总的时间复杂度为O(n(1+1/2+....+1/2k))=O(n) , 明显比冒泡快,虽然递归深度是一样的,但是每一趟时间复杂度降低 。
5. 红黑树的定义和解释?B树的基本性质?
红黑树:
性质1. 节点是红色或黑色 。
性质2. 根节点是黑色 。
性质3. 每个叶子结点都带有两个空的黑色结点(被称为黑哨兵),如果一个结点n的只有一个左孩子,那么n的右孩子是一个黑哨兵;如果结点n只有一个右孩子,那么n的左孩子是一个黑哨兵 。
性质4 每个红色节点的两个子节点都是黑色 。(从每个叶子到根的所有路径上不能有两个连续的红色节点)

推荐阅读