二分法和单调队列的专题结束了,对于做题情况很不满意。最近这几个专题做题的效率都很低,学习起来也有些吃力,总是看的时候感觉懂了,可实际做起题来却发现还差得远呢。这两天在做USACO上的题,感觉刚开始这几道难度还可以,希望后面不会太难。有一次提交的时候忘记把读文件的代码注释掉了,这个老师之前强调过的,还是犯了实在不应该,以后一定要更加小心才行。
接下来总结一下二叉树BT
性质:
1.在二叉树的第i层上最多有2^(i-1)个结点(i>=1)
2.深度为k的二叉树至多有2^k –1个结点(k>=1)注:一棵深度为k且有2k–1个结点的二叉树称为满二叉树。
3.对任意一棵二叉树,如果其叶结点数为n0,度为2的结点数为n2,则一定满足:n0=n2+1。
4.具有n个结点的完全二叉树的深度为floor(log2n)+1
5.对于一棵n个结点的完全二叉树,对任一个结点(编号为i),有:①如果i=1,则结点i为根,无父结点;如果i>1,则其父结点编号为i/2。如果2i>n,则结点i无左孩子(当然也无右孩子,为什么?即结点i为叶结点);否则左孩子编号为2i。②如果2i+1>n,则结点i无右孩子;否则右孩子编号为2i+1。
二叉树的存储结构
链式存储结构,即单链表结构或双链表结构(同树)
typedef struct node;
typedef node *tree;
struct node
{
char data;
tree lchild, rchild;
};
tree bt;
或:
typedef struct node;
typedef node *tree;
struct node
{
char data;
tree lchild, rchild,father;
};
tree bt;
顺序存储结构,即几个数组加一个指针变量
const int n = 10;
char data[n];
char lchild[n];
char rchild[n];
int bt; //根结点指针
先序遍历的操作:
若二叉树为空,则空操作,否则
①访问根结点
②先序遍历左子树
③先序遍历右子树
void preorder(tree bt) //先序遍历根结点为bt的二叉树的递归算法
{
if(bt)
{
cout << bt->data;
preorder(bt->lchild);
preorder(bt->rchild);
}
}
中序遍历的操作:
若二叉树为空,则空操作,否则
①中序遍历左子树
②访问根结点
③中序遍历右子树
void inorder(tree bt) //中序遍历根结点为bt的二叉树的递归算法
{
if(bt)
{
inorder(bt->lchild);
cout << bt->data;
inorder(bt->rchild);
}
}
后序遍历的操作:
若二叉树为空,则空操作,否则
①后序遍历左子树
②后序遍历右子树
③访问根结点
void postorder(tree bt) //后序遍历根结点为bt的二叉树的递归算法
{
if(bt)
{
postorder(bt->lchild);
postorder(bt->rchild);
cout << bt->data;
}
}
建立一棵二叉树
void pre_crt(tree &bt) //按先序次序输入二叉树中结点的值,生成
{
char ch;
ch = getchar(); //二叉树的单链表存储结构,bt为指向根结点的指针,'$'表示空树
if(ch != '$')
{
bt = new node; //建根结点
bt->data = ch;
pre_crt(bt->lchild); //建左子树
pre_crt(bt->rchild); //建右子树
}
else bt = NULL;
}
删除二叉树
void dis(tree &bt) //删除二叉树
{
if(bt)
{
dis(bt->lchild); //删左子树
dis(bt->rchild); //删右子树
delete bt; //释放父结点
}
}
插入一个结点到排序二叉树中
void insert(tree &bt, int n) //插入一个结点到排序二叉树中
{
if(bt)
{
if(n < bt->data) insert(bt->lchild, n);
else if(n > bt->data) insert(bt->rchild, n);
}
else
{
bt = new node; //新开一个空间
bt->data = n;
bt->lchild = bt->rchild = NULL;
}
}
在排序二叉树中查找一个数,找到返回该结点,否则返回NULL
tree findn(tree bt, int n) //在二叉树中查找一个数,找到返回该结点,否则返回NULL。
{
if(bt)
{
if(n < bt->data) findn(bt->lchild, n);
else if(n > bt->data) findn(bt->rchild, n);
else return bt;
}
else return NULL;
}
用嵌套括号表示法输出二叉树
void print(tree bt) //用嵌套括号表示法输出二叉树
{
if(bt)
{
cout << bt->data;
if(bt->lchild || bt->rchild)
{
cout << '(';
print(bt->lchild);
if(bt->rchild) cout << ',';
print(bt->rchild);
cout << ')';
}
}
}