树
定义:
树有n个节点,当n=0时,该树是空树,当n>=1时,除根结点的左右子树节点各不相同,并且每一个子树又可以当作一个树,依次类推到最后。
存储方式:
数组存储: 存储树必须要存储各个节点之间的关系,为了存储这种关系,需要定义一种结构体
代码语言:javascript复制struct Node
{
int value
int parent,firstchild; //此种定义方式方便节点寻找子节点,双亲节点
}
struct Node
{
int value
int parent,right; //此种定义方式方便寻找双亲还有兄弟
}
用一维数组将各个节点存储在数组中。 链表存储:
代码语言:javascript复制struct Node
{
int data;
Node *child1,.....child;//存储子节点
}
这种方式存储节点的方式较为麻烦与浪费空间,并且每一个节点的子节点数量不同,选用最多的子节点数来设置子节点数目会导致空间的浪费,变换的方式会很复杂。
代码语言:javascript复制struct Node
{
int data;
Node *child,Node *right; //存储第一个子节点与右兄弟节点
}
二叉树
定义
二叉树也是树的一种,二叉树中的两个指针是左子节点与右子节点
代码语言:javascript复制struct Node
{
int data;
Node *rchild,*lchild; //存储节点的右子节点与左子节点
}
遍历方式
先序遍历: 先遍历根节点,在遍历左子树,最终遍历右子树 后序遍历: 先遍历左子树,在遍历右子树,最终遍历根节点 中序遍历: 先遍历左子树,然后遍历根节点,最终遍历右子树
通常实现二叉树遍历可以可以使用递归的思想,这种遍历方式的好处是代码简洁,代码数量少,但是缺点是需要占用大量的内存,执行速度慢。 实现代码:
代码语言:javascript复制void preprint(Node *t)
{
if (t)
{
return;
}
cout<<t->data;
preprint(t—>lchild);
preprint(t—>rchild);
}
上述代码实现的是前序遍历,而实现中序遍历与后序遍历仅仅是将cout<data;改变一下位置即可。
为了减少遍历的时间,还可以对二叉树进行非递归的遍历 前序遍历代码:
代码语言:javascript复制 stack<Tree*> all;
all.push(first);
cout<<first->value;
while(1)
{
if(all.top()->l)
{
all.push(all.top()->l);
cout<<all.top()->value;
}
else{
break;
}
}
while(!all.empty())
{
if(all.top()->r)
{
all.push(all.top()->r);
cout<<all.top()->value;
break;
}
else{
all.pop();
}
}
中序遍历,后序遍历同样也可以使用栈方式进行遍历。
总结
树的遍历操作使用递归的方式遍历代码会相对简单,但是占用的内存比非递归要明显增多,至于那种方式都可。