习题课1-1
栈
-
因为不支持下标访问,所以自己开一个数组
-
解答
stack;
int n,top;
入栈:
top = top + 1;
Stack[top] = name
弹出栈顶
String ret = Stack[top]
top = top - 1;
return ret;
查出指定位置的元素
return Stack[pos]
队列
-
把栈倒过来就是队列了,为了支持下标查询,也需要新开一个数组
-
由于是双向的,所以需要头尾指针
-
解答
String queue[N];
int head,tail;
队尾入队:
// tail指的是最后一个元素后相邻的一个存储空间
queue[tail] = name;
tail = tail + 1;
队首出队
// head指的是第一个元素
String ret = queue[head];
head = head + 1;
return ret
访问某个位置
// pos之队列中的相对位置,如第二个,所以就等于head+2-1 = head + 1
return queue[head+pos-1]
其他:如何保证在整个过程中,队列中人数都不会超过k,但入队次数会超过k,如何用一个大小为k的数组解决?、
循环队列
数组模拟:用两个变量head和tail分别记录对头和队尾的最后一位
若head或tail达到了数组的最大长度位置,则让head或者tail等于0
队列为空:
if (tail == N)
tail = 0
if (head == N)
head = 0
int p = head + pos -1;
if (p >= N )
p -= N
二叉树
-
二叉排序树,根比左大,比右小
-
前序遍历,根在前,中序遍历,根在中,后序遍历,根在后
-
解答
前序遍历:输出自己 + 输出左子树 + 输出右子树
后序遍历:输出左子树 + 输出右子树 + 输出自己
int N = 100005;
class node{
public int val;
public int l;
public int r;
}
Node[] t = new Node[N];
二叉树初始化
将list中的节点遍历,插入树中
// root是整个二叉树的根节点
// cnt表示整个二叉树的大小
root = cnt = 0;
//插入:在以x为根节点的树中插入一个数字v
// v:要插入的数字
// x:当前节点
// 返回值:x
int insert(int v,int x){
// 数组长度为0
if(x==0){
// 若当前节点不存在,则将x变成一个新节点
cnt = cnt +1;
// 二叉树节点数组中的位置
x = cnt;
// 节点初始化
t[x].r = 0;
t[x].l = 0;
t[x].val = v;
return x;
}
// 递归插入左右子树
// 不同的节点,但都是相同的这个操作
if(t[x].val > v){
t[x].l = insert(v,t[x].l);
}else {
t[x].r = insert(v,t[x].r);
}
return x;
}
求以x为根的前序遍历dlr()
void dlr(int x,List<Integer> ans){
// 不是一个空树
if(x!=0){
// 加入x节点的val到ans中,递归求解左右子树
// 左右递归分支的上面位置是前序遍历框架
// ans.push_back(x);// c++
ans.add(x);//java // 添加自己
dlr(t[x].l,ans); // 添加自己的左子树
dlr(t[x].r,ans); // 添加自己的右子树
}
}
求以x为根的后序遍历
void lrd(int x,List<Integer> ans){
if(x!=0){
// ans.push_back(x);// c++
lrd(t[x].l,ans); // 添加自己的左子树
lrd(t[x].r,ans); // 添加自己的右子树
ans.add(x);//java // 添加自己
// 左右递归分支的下面位置是后序遍历框架
}
}