早起的虫儿被鸟吃
* 二叉树的存储:链式存储和数组。
* 二叉树的遍历:先序、中序、后序、层序。
二叉树的遍历 层序遍历 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 void LayerOrder (node* root) { queue <node*> q; root->layer = 1 ; q.push(root); while (!q.empty()){ node* p = q.front(); q.pop(); printf ("%d " , p->data); if (p->left != NULL ) { p->left->layer = p->layer + 1 ; q.push(p->left); } if (p->right != NULL ) { p->right->layer = p->layer + 1 ; q.push(p->right); } } }
建立二叉树 已知先序中序 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 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 = inL; for (; k < inR; k++) if (in[k] == root->data) break ; int numLeft = k - inL; root->left = create(preL + 1 , preL + numLeft, inL, k - 1 ); root->right = create(preL + numLeft + 1 , preR, k + 1 , inR); return root; }
二叉查找树(BST) * 左边小右边大
* 对二叉查找树进行"中序"遍历,遍历结果是有序的
* 如果给定序列是有序的或者排序后有序,可以中序递归建立BST
查找操作 1 2 3 4 5 6 7 8 9 10 11 12 void search (node* root, const int x) { if (root == NULL ) { printf ("search failed!\n" ); return ; } if (x == root->data) printf ("%d\n" , root->data); else if (x < root->data) search(root->left, x); else search(root->right, x); }
插入操作 1 2 3 4 5 6 7 8 9 10 11 12 13 void insert (node* &root, const int x) { if (root == NULL ) { root = new node; root->data = x; root->left = root->right = NULL ; return ; } if (x == root->data) return ; else if (x < root->data) insert(root->left, x); else insert(root->right, x); }
二叉查找树的建立 1 2 3 4 5 node* create (int data[]) { node* root = NULL ; for (const auto val : data) insert(root, val); return root; }
二叉查找树的删除 1 2 3 4 5 6 7 8 9 10 11 12 node* findMAX (node* root) { while (root->right != NULL ) root = root->right; return root; } node* findMin (node* root) { while (root->left != NULL ) root = root->left; return root; }
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 void deleteNode (node* root, int x) { if (root == NULL ) return ; if (x == root->data) { if (root->left == NULL && root->right == NULL ) root = NULL ; else if (root->left != NULL ) { node* pre = findMAX(root->left, x); root->data = pre->data; deleteNode(root->left, pre->data); } else { node* next = findMin(root->right); root->data = next->data; deleteNode(root->right, next->data); } } else if (x < root->data) deleteNode(root->left, x); else deleteNode(root->right, x); }
平衡二叉树(AVL树) * AVL树是一棵二叉查找树
* 任意结点的左右子树高度之差(平衡因子)的绝对值不超过1
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 struct node { int v, height; node *left, *right; }; int getHeight (node* root) { if (root == NULL ) return 0 ; else return root->height; } int getBalanceFactor (node* root) { return getHeight(root->left) - getHeight(root->right); } void updateHeight (node* root) { root->height = max(getHeight(root->left), getHeight(root->right)) + 1 ; }
查找操作 1 2 3 4 5 6 7 8 9 10 11 12 void search (node* root, const int x) { if (root == NULL ) { printf ("search failed!\n" ); return ; } if (x == root->data) printf ("%d\n" , root->data); else if (x < root->data) search(root->left, x); else search(root->right, x); }
插入操作 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 void L (node* &root) { node* p = root->right; root->right = p->left; p->left = root; updateHeight(root); updateHeight(p); root = p; } void R (node* &root) { node* p = root->left; root->left = p->right; p->right = root; updateHeight(root); updateHeight(p); root = p; }
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 void insert (node* &root, const int v) { if (root == NULL ) { root = new node; root->v = v; root->height = 1 ; root->left = root->right = NULL ; return ; } if (v < root->v) { insert(root->left, v); updateHeight(root); if (getBalanceFactor(root) == 2 ) { if (getBalanceFactor(root->left) == 1 ) R(root); else if (getBalanceFactor(root->left) == -1 ) { L(root->left); R(root); } } } else { insert(root->right, v); updateHeight(root); if (getBalanceFactor(root) == -2 ) { if (getBalanceFactor(root->right) == -1 ) L(root); else if (getBalanceFactor(root->left) == 1 ) { R(root->right); L(root); } } } }
AVL树的建立 1 2 3 4 5 node* create (int data[]) { node* root = NULL ; for (const auto v : data) insert(root, v); return root; }
并查集 * 合并:合并两个集合
* 查找:判断两个元素是否在一个集合
* 并查集产生的每一个集合都是一棵树
* int father[N]; //并查集数组
初始化 1 2 for (int i = 1 ; i <= N; i++) father[i] = i;
查找 1 2 3 4 5 6 7 8 9 10 int findFather (int x) { while (x != father[x]) x = father[x]; return x; } int findFather (int x) { if (x == father[x]) return x; else return findFather(father[x]); }
合并 1 2 3 4 5 6 void Union (int a, int b) { int faA = findFather(a); int faB = findFather(b); if (faA != faB) father[faA] = faB; }
路径压缩 1 2 3 4 5 6 7 8 9 10 11 12 int findFather (int v) { if (v == father[v]) return v; else { int root = findFather(father[v]); father[v] = root; return root; } }
堆与堆排序 * 堆是一个完全二叉树
* 大顶堆 和 小顶堆
* 堆可以用来实现优先队列
* int heap[maxn], n; // n为元素个数
向下调整 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 void downAdjust (int low, int high) { int i = low, j = i * 2 ; while (j <= high) { if (j + 1 <= high && heap[j+1 ] > heap[j]) j = j + 1 ; if (heap[j] > heap[i]) { swap(heap[j], heap[i]); i = j; j = i * 2 ; } else break ; } }
建堆 1 2 3 4 5 6 7 8 void createHeap () { for (int i = n / 2 ; i >= 1 ; i--) { downAdjust(i, n); } }
删除堆顶 1 2 3 4 5 void deleteTop () { heap[1 ] = heap[n--]; downAdjust(1 ,n); }
向上调整 1 2 3 4 5 6 7 8 9 10 11 12 void upAdjust (int low, int high) { int i = high, j = i / 2 ; while (j >= low){ if (heap[i] > heap[j]){ swap(heap[i], heap[j]); i = j; j = i / 2 ; } else break ; } }
堆的插入 1 2 3 4 void insert (node* root, int x) { heap[++n] = x; upAdjust(1 , n); }
堆排序(heap sort) 1 2 3 4 5 6 7 void heapSort () { createHeap(); for (int i = n; i > 1 ; i--){ swap(heap[1 ], heap[i]); downAdjust(1 ,i - 1 ); } }
哈夫曼树 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 #include <cstdio> #include <vector> #include <queue> using namespace std ;priority_queue<long long , vector <long long >, greater<long long > > q; int main () { int n; long long temp, x, y, ans = 0 ; scanf ("%d" , &n); for (int i = 0 ; i < n; i++){ scanf ("%lld" , &temp); q.push(temp); } while (q.size() > 1 ) { x = q.top(); q.pop(); y = q.top(); q.pop(); q.push(x + y); ans += x + y; } printf ("%lld\n" , ans); return 0 ; }
<
动态规划专题
Be a magical developer
>