一.先序遍历
根结点——> 左子树——> 右子树
void preorder(node* root) {
if(root == NULL) return;
printf("%d\n", root->data);
preorder(root->lchild);
preorder(root->rchild);
}
性质:序列的第一个一定是根结点;
二.中序遍历
左子树——> 根结点——> 右子树
void inorder(node* root) {
if(root == NULL) return;
inorder(root->lchild);
printf("%d\n", root->data);
inorder(root->rchild);
}
性质:只要知道根结点,就可以区分左子树和右子树;
三.后序遍历
左子树——> 右子树——> 根结点
void postorder(node* root) {
if(root == NULL) return;
postorder(root->lchild);
postorder(root->rchild);
printf("%d\n", root->data);
}
性质:序列的最后一个是根结点
四.层序遍历
1.实现代码:
void LayerOrder(node* root) {
queue<node*> q;
q.push(root);
while(!q.empty()) {
node* now = q.front();
q.pop();
printf("%d", now->data);
if(now->lchild != NULL) q.push(now->lchild);
if(now->rchild != NULL) q.push(now->rchild);
}
}
2.记录层号:
void LayerOrder(node* root) {
queue<node*> q;
root->layer = 1;
q.push(root);
while(!q.empty()) {
node* now = q.front();
q.pop();
printf("%d", now->data);
if(now->lchild != NULL) {
now->lchild->layer = now->layer + 1;
q.push(now->lchild);
}
if(now->rchild != NULL) {
now->rchild->layer = now->layer + 1;
q.push(now->rchild);
}
}
}
3.用先序遍历和中序遍历重建二叉树:
struct node {
int data;
node* lchild;
node* rchild;
};
node* create(int preL, int preR, int inL, int inR) {
if(preL > preR) return NULL;
node* root = new node;
root->data = pre[preL];
int k;
for(k = inL; k <= inR; k++) {
if(in[k] == pre[preL]) break;
}
int numLeft = k - inL;
root->lchild = create(preL + 1, preL + numLeft, inL, k - 1);
root->rchild = create(preL + numLeft + 1, preR, k + 1, inR);
return root;
}
4.用层序遍历和中序遍历重建二叉树:
struct node {
int data;
node* lchild;
node* rchild;
};
node* create(int layerL, int layerR, int inL, int inR) {
if(layerL > layerR) return NULL;
node* root = new node;
root->data = layer[layerL];
int k;
for(k = inL; k <= inR; k++) {
if(in[k] = layer[layerL]) break;
}
int numLeft = k - inL;
root->lchild = create(layerL * 2, layerR, inL, k - 1);
root->rchild = create(layerL * 2 + 1, layerR, k + 1, inR);
return root;
}
五.二叉树的静态实现
不使用指针的实现方式
//定义:
struct node {
typename data;
int lchild; //左结点数组下标
int rchild; //右结点数组下标
}Node[maxn]; //maxn 为结点上限个数
//新结点生成:
int index = 0;
int newNode(int v) {
Node[index].data = v;
Node[index].lchild = -1;
Node[index].rchild = -1;
return index++;
}
//查找、修改:
void search(int root, int x, int newdata) {
if(root == -1) return;
if(Node[root].data == x) Node[root].data = newdata;
search(Node[root].lchild, x, newdata);
search(Node[root].rchild, x, newdata);
}
//插入:
void insert(int &root, int x) {
if(root == -1) {
root = newNode(x);
return;
}
if(x应该插在左子树) insert(Node[root].lchild, x);
else insert(Node[root].rchild, x);
}
//建立:
int Create(int data[], int n) {
int root = -1;
for(int i = 0; i < n; i++) insert(root, data[i]);
return root;
}
六.题目:
1.PAT A1020
注意:
1).输出格式:printf("%d", temp->data); num++; if(num < n) printf(" ");
代码:
#include<cstdio>
#include<queue>
using namespace std;
const int maxn = 40;
int post[maxn], in[maxn];
int num = 0;
int n;
struct node {
int data;
node* lchild;
node* rchild;
};
node* create(int postL, int postR, int inL, int inR) {
if(postL > postR) return NULL;
node* root = new node;
root->data = post[postR];
int k;
for(k = inL; k <= inR; k++) {
if(in[k] == post[postR]) break;
}
int numLeft = k - inL;
root->lchild = create(postL, postL + numLeft - 1, inL, k - 1);
root->rchild = create(postL + numLeft, postR - 1, k + 1, inR);
return root;
}
void print(node* root) {
if(root == NULL) return;
queue<node*> q;
q.push(root);
while(!q.empty()) {
node* temp = q.front();
q.pop();
printf("%d", temp->data);
num++;
if(num < n) printf(" ");
if(temp->lchild != NULL) q.push(temp->lchild);
if(temp->rchild != NULL) q.push(temp->rchild);
}
}
int main() {
scanf("%d", &n);
for(int i = 0; i < n; i++) scanf("%d", &post[i]);
for(int i = 0; i < n; i++) scanf("%d", &in[i]);
node* root = create(0, n - 1, 0, n - 1);
print(root);
return 0;
}
2.PAT A1086
思路:
1).如何输入:先输入%s,判定是 Push/Pop:if(strcmp(str, "Push") == 0)
,再输入数字或者不输入数字,再进行之后的操作;
2).模拟栈,用 stack;
代码:
#include<cstdio>
#include<stack>
#include<cstring>
using namespace std;
const int maxn = 40;
int n, num = 0;
int pre[maxn], in[maxn];
struct node {
int data;
node* lchild;
node* rchild;
};
node* create(int preL, int preR, int inL, int inR) {
if(preL > preR) return NULL;
node* root = new node;
root->data = pre[preL];
int k;
for(k = inL; k <= inR; k++) {
if(in[k] == pre[preL]) break;
}
int numLeft = k - inL;
root->lchild = create(preL + 1, preL + numLeft, inL, k - 1);
root->rchild = create(preL + numLeft + 1, preR, k + 1, inR);
return root;
}
void print(node* root) {
if(root == NULL) return;
print(root->lchild);
print(root->rchild);
printf("%d", root->data);
num++;
if(num < n) printf(" ");
}
int main() {
scanf("%d", &n);
char str[5];
stack<int> st;
int x, preIndex = 0, inIndex = 0;
for(int i = 0; i < 2 * n; i++) {
scanf("%s", str);
if(strcmp(str, "Push") == 0) {
scanf("%d", &x);
pre[preIndex++] = x;
st.push(x);
}
else {
in[inIndex++] = st.top();
st.pop();
}
}
node* root = create(0, n - 1, 0, n - 1);
print(root);
return 0;
}
3.PAT A1102
思路:
如何输入:scanf("%*c%c %c", &x1, &x2);
%*c 表示接收一个换行符;
代码:
#include<cstdio>
#include<queue>
using namespace std;
const int maxn = 20;
int n;
int num1 = 0, num2 = 0;
struct node {
int data;
int lchild;
int rchild;
bool flag;
}Node[maxn];
void layerPrint(int root) {
queue<int> q;
q.push(root);
while(!q.empty()) {
int temp = q.front();
q.pop();
printf("%d", Node[temp].data);
num1++;
if(num1 < n) printf(" ");
else printf("\n");
if(Node[temp].lchild != -1) q.push(Node[temp].lchild);
if(Node[temp].rchild != -1) q.push(Node[temp].rchild);
}
}
void inPrint(int root) {
if(root == -1) return;
inPrint(Node[root].lchild);
printf("%d", root);
num2++;
if(num2 < n) printf(" ");
else printf("\n");
inPrint(Node[root].rchild);
}
int main() {
scanf("%d", &n);
char x1, x2;
for(int i = 0; i < n; i++) Node[i].flag = true;
for(int i = 0; i < n; i++) {
scanf("%*c%c %c", &x1, &x2);
Node[i].data = i;
if(x1 == '-') Node[i].rchild = -1;
else {
Node[i].rchild = x1 - '0';
Node[x1 - '0'].flag = false;
}
if(x2 == '-') Node[i].lchild = -1;
else {
Node[i].lchild = x2 - '0';
Node[x2 - '0'].flag = false;
}
}
int i;
for(i = 0; i < n; i++) {
if(Node[i].flag == true) break;
}
int root_i = i;
layerPrint(root_i);
inPrint(root_i);
return 0;
}