初阶数据结构易错点整理

一、时间复杂度

不能直接数循环的个数或者循环的嵌套个数,因为不一定每个循环都在执行整体的次数,需要具体问题具体分析,比如以下代码,这里的 i 以二的指数的速度增大,所以时间复杂度是O(logN)

cpp 复制代码
void fun(int n) {
  int i=l;
  while(i<=n)
    i=i*2;
}

二、循环队列

我们通过顺序表来实现,其实最难判断的点就是队列已满和队列为空,所以采取简单的方法是,如果我们需要存储 k 个数据的循环队列,那么我们只需要开 (k + 1)的空间,这样的话让队尾(rear)指向最后一个数据的下一个,这是如果(rear+1)%(k + 1)就是队头,则队列已满;若是队尾等于队头,则队列为空

在就是关于大小的判断,一般来说(rear - front)就是数据个数,但是会出现队尾在前队头在后的情况,就是队尾循环走了一次整个空间,所以我们这里用(rear + k - front)但是还可能不是队尾在队头之前,所以最后的正确计算是(rear + k - front)%(k)

三、队列、栈插入删除数据的特点

队列只能从右侧进入,左侧删除(一头删,一头进),栈只能从右侧进,右侧删(一头进和删),所以,说栈和队列都能从两侧进行插入删除是错的

四、栈在只剩一个数据的时候

要注意尾指针是否需要置空,防止野指针问题

五、二叉树的前序、中序、后序遍历

首先明确概念:

前序:根、左子树、右子树

中序:左子树、根、右子树

后序:左子树、右子树、根

在这里,前序遍历相当于深度优先遍历------先遍历完一条完整的路径(从根节点到叶节点的完整路径),在反上来遍历下一条

然后,对于笔试题来说,前序序列最大的用处就是确定根节点,中序序列最大的用处就是确定子树(左子树是哪些节点,右子树是那些节点,这里判断出来的不是顺序,是有哪些),后序就是前序的逆置,看的方法就是从后往前看,一次是根、右子树、左子树。

例如以下题目:

已知某二叉树的中序遍历序列为JGDHKBAELIMCF,后序遍历序列为JGKHDBLMIEFCA,则其前序遍历序列为( )

首先,从后序序列可以看出整棵树的根节点是A, 再到中序序列看左右子树,可知左子树的节点有JGDHKB,右子树的节点有JGDHKB;接下来再看后序序列,A之后访问了C,说明右子树的根节点是C, 在所有右子树的根节点之后第一个出现的左子树节点是B,所以左子树的根是B,到这里我们已经完成了二叉树第一层和第二层的构建;对于B来说,为了判断他的左右子树情况,我们看中序序列,发现剩下所有的未构建的A的左子树的节点都在B的左边,说明B没有右子树,接下来确定B的左子树的根节点,看后序序列,发现B后访问了D,说明该根节点是D, 一次往复,就可以完成整棵二叉树的复原,如下图所示: