1.树的根节点没有前驱结点,除根节点以外的其他结点只有一个前驱结点。
2.树中所有结点有0或多个后继结点。
3.结点的度:结点所拥有的的子树个数。
树的度:树中各节点的最大度数。
4.分支结点(非终端结点):度不为0的结点。也就是说,除了叶节点的都是非终端节点。
5.根节点层数为1。
6.二叉树有5种基本形态。(空树,只有根节点,有左子树,有右子树,有左右子树)
7.满二叉树与完全二叉树
8.性质
(1) 一棵非空二叉树的第i层上最多有2的i-1次方个结点。
(2)深度为k的二叉树中,最多有2的k次方-1个结点。
(3)对于非空二叉树,若叶子结点数为n0,度数为2的结点数为n2,则n0=n2+1。(可以先设想 一个二叉树只有根节点,二叉树有一个叶节点,也就是这个根节点,没有度数为2的结点; 对这个根节点只添加左孩子或者右孩子的话,依旧只有一个叶节点,没有度数为2的结点; 如果对这个根节点同时添加左孩子与右孩子,这样叶节点+1,度数为2的结点+1)
(4)有n个结点的完全二叉树的深度为log2(n)的下取整+1。(必须是完全二叉树)
(5)编号为i的结点,当2*i不超过范围时,左孩子为2*i;当2*i+1不超过范围时, 右孩子为 2*i+1;父节点为i/2下取整
9.二叉树存储
(1)顺序存储:数组(使用性质5)
(2)链式存储:二叉链表存储,三叉链表存储(多了一个指向父节点的指针)
10.遍历操作
(1)递归遍历
#include<iostream>
using namespace std;
typedef struct bitnode {
int data;
bitnode* lchild, *rchild;
}BiTree;
void PreOrder(BiTree* t) {
if (t == NULL) {
return;
}
cout << t->data;
PreOrder(t->lchild);
PreOrder(t->rchild);
}
void InOrder(BiTree* t) {
if (t == NULL) {
return;
}
PreOrder(t->lchild);
cout << t->data;
PreOrder(t->rchild);
}
void PostOrder(BiTree* t) {
if (t == NULL) {
return;
}
PreOrder(t->lchild);
PreOrder(t->rchild);
cout << t->data;
}
int main()
{
//创建二叉树
//遍历
return 0;
}
(2)迭代法遍历
用这个题创建的二叉树
4-14 还原二叉树&&4-15 根据后序和中序遍历输出先序遍历
#include<iostream>
#include<stack>
#include<vector>
using namespace std;
typedef struct bitnode {
char data;
bitnode* lchild, *rchild;
}BiTree;
BiTree* get(char preod[], char inod[], int len) {
int i;
if (len <= 0) {
return NULL;
}
BiTree* t = (BiTree*)malloc(sizeof(BiTree));
t->data = preod[0];
for (i = 0; inod[i] != preod[0]; i++);
t->lchild = get(preod + 1, inod, i);
t->rchild = get(preod + i + 1, inod + i + 1, len - i - 1);
return t;
}
vector<char> InOrder(BiTree* t) {//左中右
vector<char> result;
stack<BiTree*> temp;
if (t != NULL) {
temp.push(t);
}
while (!temp.empty()) {
bitnode* node = temp.top();
if (node != NULL) {
temp.pop();
if (node->rchild != NULL) {
temp.push(node->rchild);
}
temp.push(node);
temp.push(NULL);
if (node->lchild != NULL) {
temp.push(node->lchild);
}
}
else {
temp.pop();
node = temp.top();
temp.pop();
result.push_back(node->data);
}
}
return result;
}
vector<char> PreOrder(BiTree* t) {//中左右
vector<char> result;
stack<BiTree*> temp;
if (t != NULL) {
temp.push(t);
}
while (!temp.empty()) {
bitnode* node = temp.top();
if (node != NULL) {
temp.pop();
if (node->rchild != NULL) {
temp.push(node->rchild);
}
if (node->lchild != NULL) {
temp.push(node->lchild);
}
temp.push(node);
temp.push(NULL);
}
else {
temp.pop();
node = temp.top();
temp.pop();
result.push_back(node->data);
}
}
return result;
}
vector<char> PostOrder(BiTree* t) {//左右中
vector<char> result;
stack<BiTree*> temp;
if (t != NULL) {
temp.push(t);
}
while (!temp.empty()) {
bitnode* node = temp.top();
if (node != NULL) {
temp.pop();
temp.push(node);
temp.push(NULL);
if (node->rchild != NULL) {
temp.push(node->rchild);
}
if (node->lchild != NULL) {
temp.push(node->lchild);
}
}
else {
temp.pop();
node = temp.top();
temp.pop();
result.push_back(node->data);
}
}
return result;
}
int main()
{
int n;
scanf("%d", &n);
char s1[200], s2[200];
scanf("%s", &s1);
scanf("%s", &s2);
BiTree* t = get(s1, s2, n);
vector<char> v = InOrder(t);
for (auto it = v.begin(); it != v.end(); it++) {
cout << *it;
}
return 0;
}
(3)层次遍历
练习题:二叉树的层序遍历 专题
#include<iostream>
#include<queue>
#include<vector>
using namespace std;
typedef struct bitnode {
char data;
bitnode* lchild, *rchild;
}BiTree;
BiTree* get(char preod[], char inod[], int len) {
int i;
if (len <= 0) {
return NULL;
}
BiTree* t = (BiTree*)malloc(sizeof(BiTree));
t->data = preod[0];
for (i = 0; inod[i] != preod[0]; i++);
t->lchild = get(preod + 1, inod, i);
t->rchild = get(preod + i + 1, inod + i + 1, len - i - 1);
return t;
}
vector<char> LevelOrder(BiTree* t) {
vector<char> result;
queue<bitnode*> st;
if (t != NULL) {
result.push_back(t->data);
st.push(t);
}
bitnode* temp;
while (!st.empty()) {
temp = st.front();
st.pop();
if (temp->lchild != NULL) {
result.push_back(temp->lchild->data);
st.push(temp->lchild);
}
if (temp->rchild != NULL) {
result.push_back(temp->rchild->data);
st.push(temp->rchild);
}
}
return result;
}
int main()
{
int n;
scanf("%d", &n);
char s1[200], s2[200];
scanf("%s", &s1);
scanf("%s", &s2);
BiTree* t = get(s1, s2, n);
vector<char> v = LevelOrder(t);
for (auto it = v.begin(); it != v.end(); it++) {
cout << *it;
}
return 0;
}
11.根据给定序列构造二叉树
例如:给定二叉树的先序序列:ABD0G000CE00F00(0表示空)
#include<iostream>
#include<queue>
#include<vector>
using namespace std;
typedef struct bitnode {
char data;
bitnode* lchild, *rchild;
}BiTree;
BiTree* creat() {
bitnode* node;
char ch;
scanf("%c", &ch);
if (ch == '0') {
return NULL;
}
else {
node = (bitnode*)malloc(sizeof(bitnode));
node->data = ch;
node->lchild = creat();
node->rchild = creat();
}
return node;
}
vector<char> LevelOrder(BiTree* t) {
vector<char> result;
queue<bitnode*> st;
if (t != NULL) {
result.push_back(t->data);
st.push(t);
}
bitnode* temp;
while (!st.empty()) {
temp = st.front();
st.pop();
if (temp->lchild != NULL) {
result.push_back(temp->lchild->data);
st.push(temp->lchild);
}
if (temp->rchild != NULL) {
result.push_back(temp->rchild->data);
st.push(temp->rchild);
}
}
return result;
}
int main()
{
BiTree* t = creat();
vector<char> v = LevelOrder(t);
for (auto it = v.begin(); it != v.end(); it++) {
cout << *it;
}
return 0;
}
12.查找数据
用四种遍历方式都可以,当用迭代法时,遇到这个元素就直接返回就行;用递归法时,不能直接返回。
13.由遍历顺序恢复二叉树。(1)先序和中序(2)后序与中序
4-14 还原二叉树&&4-15 根据后序和中序遍历输出先序遍历
14.线索二叉树
先序线索二叉树,中序线索二叉树,后序线索二叉树。
#include<iostream>
#include<queue>
#include<vector>
using namespace std;
typedef struct bitnode {
char data;
int ltag, rtag;
bitnode* lchild, * rchild;
}BiTree;
BiTree* get(char preod[], char inod[], int len) {
int i;
if (len <= 0) {
return NULL;
}
BiTree* t = (BiTree*)malloc(sizeof(BiTree));
t->data = preod[0];
t->ltag = t->rtag = 0;
for (i = 0; inod[i] != preod[0]; i++);
t->lchild = get(preod + 1, inod, i);
t->rchild = get(preod + i + 1, inod + i + 1, len - i - 1);
return t;
}
bitnode* pre;
void InTreading(bitnode* p) {
if (p) {
InTreading(p->lchild);
if (p->lchild == NULL) {
p->ltag = 1;
p->lchild = pre;
}
if (pre->rchild == NULL) {
pre->rtag = 1;
pre->rchild = p;
}
pre = p;
InTreading(p->rchild);
}
}
bitnode* InOrderThr(bitnode* T) {
bitnode* head = (bitnode*)malloc(sizeof(bitnode));
head->ltag = 0;
head->rtag = 1;
head->rchild = head;
if (!T) {
head->lchild = head;
}
else {
head->lchild = T;
pre = head;
InTreading(T);
pre->rchild = head;
pre->rtag = 1;
head->rchild = pre;
}
return head;
}
bitnode* InPostNode(bitnode* p) {
bitnode* post;
post = p->rchild;
if (p->rtag != 1) {
while (post->ltag == 0) {
post = post->lchild;
}
}
return post;
}
void Search(bitnode* head) {
bitnode* p;
p = head->lchild;
while (p->ltag == 0 && p != head) {
p = p->lchild;
}
while (p != head) {
cout << p->data << " ";
p = InPostNode(p);
}
}
int main()
{
int n;
scanf("%d", &n);
char s1[200], s2[200];
scanf("%s", &s1);
scanf("%s", &s2);
BiTree* t = get(s1, s2, n);
t = InOrderThr(t);
Search(t);
return 0;
}
15.哈夫曼树
16.哈夫曼编码
17.森林