1、重建二叉树
根据前序和中序遍历的结果,求后序遍历。
#include <stdio.h> #include <string.h> // 在中序序列中找出前序中根的位置 int Find(char in[], char ch, int s, int e) { while(s <= e && in[s] != ch) { s++; } return s; } void PostTraverse(char pre[], int ps, int pe, char in[], int is, int ie) { int k; char c; if(is > ie ) return; // 非法子树 if(is == ie) {printf("%c ", in[is]); return;} // 子树只有一个结点 // 前序序列中每个节点都是其子树的根结点 c = pre[ps]; k = Find(in, c, is, ie); // 在中序序列中找到根结点的位置 PostTraverse(pre, ps + 1, ps + k - is, in, is, k - 1); // 递归求解左子树 PostTraverse(pre, ps + k - is + 1, pe, in, k + 1, ie); // 递归求解右子树 printf("%c ", c); // 输出根结点 } int main() { char pre[] = "ABCDEGF"; char in[] = "CBEGDFA"; PostTraverse(pre, 0, strlen(in) - 1, in, 0, strlen(pre) - 1); printf("\n"); return 0; }
2、二叉树分层遍历
二叉树的分层遍历可以通过递归实现,但是相对效率较低。访问二叉树第k层结点时,只需要知道第k - 1层结点的信息,加些将k - 1层结点信息保存在数组中,以cur表示当前访问的结点,last表示当前层次的最后一个结点的下一个位置,当cur == last时当前层次访问结束。在访问第k层时,将k + 1的所有结点存入数组,当访问完第k层时,判断是否还存在新的层次可以访问,直到访问完所有层次为止。
#include <iostream> #include <vector> #include <string> using namespace std; typedef struct BiNode { char data; struct BiNode *lchild; struct BiNode *rchild; } BiTree; /* 创建二叉树, 输入:abc##de#g##f### */ void CreateBiTree(BiTree *&root) { char ch; cin >> ch; if(ch == '#') { root = NULL; } else { root = new BiNode; root->data = ch; root->lchild = root->rchild = NULL; CreateBiTree(root->lchild); CreateBiTree(root->rchild); } } /* 前序递归遍历 */ void PreOrderTraverse(const BiTree *root) { if(root) { cout << root->data << " "; PreOrderTraverse(root->lchild); PreOrderTraverse(root->rchild); } } void PrintByLevel(BiTree *root) { int cur = 0, last = 1; vector<BiTree *> vec; if(root == NULL) return; vec.push_back(root); while(cur < vec.size()) { last = vec.size(); while(cur < last) { cout << vec[cur]->data << " "; if(vec[cur]->lchild) vec.push_back(vec[cur]->lchild); if(vec[cur]->rchild) vec.push_back(vec[cur]->rchild); cur++; } cout << endl << endl; } } /* 中序递归遍 */ void InOrderTraverse(const BiTree *root) { if(root) { InOrderTraverse(root->lchild); cout << root->data << " "; InOrderTraverse(root->rchild); } } /* 后序递归遍历 */ void PostOrderTraverse(const BiTree *root) { if(root) { PostOrderTraverse(root->lchild); PostOrderTraverse(root->rchild); cout << root->data << " "; } } int main() { BiTree *root; CreateBiTree(root); /*PreOrderTraverse(root); cout << endl; InOrderTraverse(root); cout << endl; PostOrderTraverse(root); cout << endl;*/ PrintByLevel(root); return 0; }
3、给定一个数组,数组中的元素按升序排列,求其中两个元素之和为m的数对
设数组a中的元素为a1,a2,......,an,且a1<a2<......<an。令i = 1, j = n:
如果ai + aj > m,说明可能存在i < x < j使得ai + ax = m则有j--
如果ai + aj < m,说明可能存在i < x < j使得ax + aj = m则有i++
如果ai + aj = m,说明则输出(i, j)
如果i >= j,说明数组中不存在满足条件的数对。
#include <stdio.h> #define ARRSIZE 10 int main() { int m, i = 0, j = ARRSIZE - 1, n = 0; int a[ARRSIZE]; for(i = 0; i < ARRSIZE; i++) scanf("%d", &a[i]); scanf("%d", &m); i = 0; while(i < j) { if(a[i] + a[j] > m) j--; else if(a[i] + a[j] < m) i++; else { printf("(%d, %d)\n", a[i], a[j]); i++; j--; n++; } } if(i == 0) printf("没有找到数对(i, j)使得a[i] + a[j] == m"); return 0; }
4、判断两棵二叉树是否相等
两棵二叉树root1和root2相等有以下两种情况:
1.如果root1和root2都是空树
2.如果root1的左子树与root2的左子树相同且root1的右子树与root2的右子树相同
#include <iostream> #include <cstdio> #include <string> using namespace std; typedef struct BiNode { char data; struct BiNode *lchild; struct BiNode *rchild; } BiTree; /* 建立二叉树时的输入格式:abc##de#g##f### */ void CreateBiTree(BiTree *&root) { char ch; cin >> ch; if(ch == '#') { root = NULL; } else { root = new BiNode; root->data = ch; root->lchild = root->rchild = NULL; CreateBiTree(root->lchild); CreateBiTree(root->rchild); } } /* 判断两棵二叉是否相等,相等返回1,否则返回0 */ int EqualTree(BiTree *root1, BiTree *root2) { if(!root1 && !root2) return 1; if(!root1 || !root2) return 0; if(root1->data != root2->data) return 0; if(EqualTree(root1->lchild, root2->lchild) && EqualTree(root1->rchild, root2->rchild)) return 1; return 0; } int main() { BiTree *root1, *root2; CreateBiTree(root1); CreateBiTree(root2); if(EqualTree(root1, root2) == 1) cout << "equal" << endl; else cout << "not equal" << endl; return 0; }
5、求大量数据中出现频率最高的k个数