二叉树
创建一个二叉树
using namespace std; //链式结构二叉树 #define END '#'//结束符 #代表空 typedef char ElemType; typedef struct BtNode//树 { BtNode* leftchild; //BtNode* parent; BtNode* rightchild; ElemType data; }BtNode, * BinaryTree; BtNode* Buynode //购买结点 { BtNode* s = (BtNode*)malloc(sizeof(BtNode)); if (NULL == s) exit(1); memset(s, 0, sizeof(BtNode)); return s; } //先序遍历 根左右 void PreOrder(BtNode* ptr) { if (ptr != NULL) { printf("%c ", ptr->data); PreOrder(ptr->leftchild); PreOrder(ptr->rightchild); } } //中序遍历 左根右 void InOrder(BtNode* ptr) { if (ptr != NULL) { InOrder(ptr->leftchild); printf("%c ", ptr->data); InOrder(ptr->rightchild); } } //后续遍历 左右根 void PastOrder(BtNode* ptr) { if (ptr != NULL) { PastOrder(ptr->leftchild); PastOrder(ptr->rightchild); printf("%c ", ptr->data); } } //创建树 BtNode* CreateTree() { ElemType ch; BtNode* s = NULL; cin >> ch; if (ch != END) { s = Buynode(); s->data = ch; s->leftchild = CreateTree(); s->rightchild = CreateTree(); } return s; } int main() { BinaryTree root = NULL; root = CreateTree(); PreOrder(root); printf("\n"); InOrder(root); printf("\n"); PastOrder(root); printf("\n"); return 0; }
用先序和中序创建一个二叉树
//用中序序列寻找下标 int FindPos(const char* is, int n, ElemType val) { int pos = -1; for (int i = 0; i < n; ++i) { if (is[i] == val) { pos = i; break; } } return pos; } //用先序序列创建 BtNode* CreatePI(const char* ps, const char* is, int n) { BtNode* s = NULL; if (n > 0) { s = Buynode(); s->data = ps[0]; int pos = FindPos(is, n, ps[0]); if (pos == -1) exit(1); s->leftchild = CreatePI(ps + 1, is, pos); s->rightchild = CreatePI(ps + 1 + pos, is + 1 + pos, n - pos - 1); } return s; } //创建二叉树 BtNode* CreateBTreePI(const char* ps, const char* is, int n) { if (ps == NULL || is == NULL || n < 1) return NULL; else return CreatePI(ps, is, n); } int main() { const char ps[] = { "ABCDEFGH" };//先序遍历 const char is[] = { "CBEDFAGH" };//中序遍历 int n = strlen(is); BinaryTree root = NULL; root = CreateBTreePI(ps, is, n);//使用先序中序创建二叉树 return 0; }
用中序和后序创建一个二叉树
int FindPos(const char* is, int n, ElemType val) { int pos = -1; for (int i = 0; i < n; ++i) { if (is[i] == val) { pos = i; break; } } return pos; } BtNode* CreateIP(const char* is, const char* ls, int n) { BtNode* s = NULL; if (n > 0) { s = Buynode(); s->data = ls[n - 1]; int pos = FindPos(is, n, ls[n - 1]); s->leftchild = CreateIP(is, ls, pos); s->rightchild = CreateIP(is + pos + 1, ls + pos, n - pos - 1); } return s; } BtNode* CreateBTreeIP(const char* is, const char* ls, int n) { if (is == NULL || ls == NULL || n < 1) return NULL; else return CreateIP(is, ls, n); } int main() { const char is[] = { "CBEDFAGH" };//中序遍历 const char ls[] = { "CEFDBHGA" };//后续遍历 int n = strlen(is); BinaryTree root = NULL; root = CreateBTreeIP(is, ls, n);//使用中序和后续创建二叉树 return 0; }
非递归遍历规则
//非递归中序遍历 用栈 (先进后出) void NiceInOrder(BtNode* ptr) { if (ptr == NULL) return; stack<BtNode*> st; while (ptr != NULL || !st.empty()) { while (ptr != NULL) { st.push(ptr);//入栈 ptr = ptr->leftchild; } ptr = st.top(); st.pop();//取栈顶元素 cout << ptr->data << " ";//取ptr指向的值 ptr = ptr->rightchild;//指向右孩子 } cout << endl; } //非递归后续遍历规则 void NicePastOrder(BtNode* ptr) { if (ptr == NULL) return; stack<BtNode*> st; BtNode* tag = NULL;//标志位 while (ptr != NULL || !st.empty()) { while (ptr != NULL) { st.push(ptr); ptr = ptr->leftchild; } ptr = st.top(); st.pop(); if (ptr->rightchild == NULL || ptr->rightchild == tag) { cout << ptr->data << " "; tag = ptr;//代表ptr被访问过 ptr = NULL; } else { st.push(ptr); ptr = ptr->rightchild; } } cout << endl; } //前序遍历 void NicePreOrder(BtNode* ptr) { if (ptr == NULL) return; stack<BtNode*> st; st.push(ptr); while (!st.empty()) { ptr = st.top(); st.pop(); cout << ptr->data << " "; if (ptr->rightchild != NULL)//先右后左入 { st.push(ptr->rightchild); } if (ptr->leftchild != NULL) { st.push(ptr->leftchild); } } cout << endl; } //层次遍历 void NiceLevelOrder(BtNode* ptr) { if (ptr == NULL) return; queue<BtNode*> st; st.push(ptr); while (!st.empty()) { ptr = st.front(); st.pop(); cout << ptr->data << " "; if (ptr->leftchild != NULL) { st.push(ptr->leftchild); } if (ptr->rightchild != NULL) { st.push(ptr->rightchild); } } cout << endl; } int main() { const char ps[] = { "ABCDEFGH" };//先序遍历 const char is[] = { "CBEDFAGH" };//中序遍历 const char ls[] = { "CEFDBHGA" };//后续遍历 int n = strlen(is); BinaryTree root = NULL; NicePreOrder(root); NiceInOrder(root); NicePastOrder(root); NiceLevelOrder(root); return 0; }
z字型打印(应使用一个栈一个队列)
//z字形打印 void PrintZ(BtNode* ptr) { if (ptr == NULL)return; stack<BtNode*> sta; stack<BtNode*> stb; sta.push(ptr); while (!sta.empty() || !stb.empty()) { while (!sta.empty()) { ptr = sta.top(); sta.pop(); cout << ptr->data << " "; if (ptr->rightchild != NULL) { stb.push(ptr->rightchild); } if (ptr->leftchild != NULL) { stb.push(ptr->leftchild); } } while (!stb.empty()) { ptr = stb.top(); stb.pop(); cout << ptr->data << " "; if (ptr->leftchild != NULL) { sta.push(ptr->leftchild); } if (ptr->rightchild != NULL) { sta.push(ptr->rightchild); } } } cout << endl; }
如何验证二叉树为满二叉树
//满二叉树 bool IsFullBiTree(BtNode* ptr) { if (ptr == NULL)return true; queue<BtNode*> qu; qu.push(ptr); int n = 1; while(!qu.empty()) { if (n != qu.size()) { res = false; break; } int i = 0; while (i < n && &!qu.empty()) { int i = 0; while (i < n && !qu.empty()) { ptr = qu.front(); qu.pop(); ++i; if (ptr->leftchild != NULL) qu.push(ptr->leftchild); if (ptr->rightchild != NULL)qu.push(ptr->rightchild); } if (i < n) { res = false; break; } n += n;//n=n<<1 } return res; }
完全二叉树(每一层均达到最大值)
//完全二叉树(每一层都达到最大值) bool IsComBinTree(BtNode* ptr) { bool res = true; if (ptr == NULL)return res; queue<BtNode*> qu; while (!qu.empty()) { ptr = qu.front(); qu.pop(); if (ptr == NULL)break; qu.push(ptr->leftchild); qu.push(ptr->rightchild); } while (!qu.empty()) { ptr = qu.front(); qu.pop(); if (ptr != NULL) { res = false; break; } } return res; }
中序遍历后变成为一个双向链表(左孩子当做前驱,右孩子当做后继)
BtNode *NiceList(BtNode* ptr) { if (ptr == NULL) return NULL; BtNode* head = NULL; BtNode* pre = NULL; stack<BtNode*> st; while (ptr != NULL || !st.empty()) { while (ptr != NULL) { st.push(ptr);//入栈 ptr = ptr->leftchild; } ptr = st.top(); st.pop();//取栈顶元素 if (head == NULL) { head = ptr; pre = ptr; } else { pre->rightchild = ptr; ptr->leftchild = pre; } ptr = ptr->rightchild;//指向右孩子 }
head->leftchild=pre;
pre->rightchild=head; return head; } int main() { const char ps[] = { "ABCDEFGH" };//先序遍历 const char is[] = { "CBEDFAGH" };//中序遍历 const char ls[] = { "CEFDBHGA" };//后续遍历 int n = strlen(is); BinaryTree root = NULL; root = NiceList(root);//中序化 return 0; }
打印根到叶序列
//打印根到叶序列 void PrintfVec(BtNode* ptr, vector<char>& vec)//vec必须引用,保证后面保持不变 { if (ptr != NULL) { vec.push_back(ptr->data); PrintVec(ptr->leftchild, vec); PrintVec(ptr->rightchild, vec); if (ptr->leftchild == NULL && ptr->rightchild == NULL) { for (auto& x : vec) { cout << x << " "; } cout << endl; } vec.pop_back(); } } int main() { const char ps[] = { "ABCDEFGH" };//先序遍历 const char is[] = { "CBEDFAGH" };//中序遍历 const char ls[] = { "CEFDBHGA" };//后续遍历 int n = strlen(is); BinaryTree root = NULL; root = CreateBTreeIP(is, ls, n);// vector<int> vec; PrintVec(root, vec); cout << endl; return 0; }
二叉树的最大路径之和
int MaxPath(BtNode* ptr, int& maxv)//最大路径,引用:每到最大值就把他记录下来 { if (ptr == NULL) return 0; int left = max(0, MaxPath(ptr->leftchild,maxv)); int right = max(0, MaxPath(ptr->rightchild, maxv)); maxv = max(maxv, left + ptr->data + right);//与左子树大小,根,右子树大小之和进行比较 return max(0, max(left, right) + ptr->data); } int main() { int pa[] = { -10,9,20,15,7 }; int ia[] = { 9,-10,15,20,7 }; int n = sizeof(pa) / sizeof(pa[0]); BinaryTree root = CreatePI(pa, ia, n); NiceInOrder(root); int maxv = INT_MIN; MaxPath(root, maxv); cout << maxv << endl; return 0; }
二叉搜索树的建立
typedef int KeyType; typedef struct BstNode { struct BstNode* leftchild; //struct BstNode* parent; struct BstNode* rightchild; KeyType key; }BstNode, * BSTree; BstNode* Buynode() { BstNode* s = (BstNode*)malloc(sizeof(BstNode)); if (NULL == s) exit(1); memset(s, 0, sizeof(BstNode)); return s; } BstNode* MakeRoot(KeyType kx)//购买根节点 { BstNode* s = Buynode(); s->key = kx; return s; } //查询 BstNode* FindValue(BstNode* ptr, KeyType kx) { if (ptr == NULL || ptr->key == kx) { return ptr; } else if (kx < ptr->key) { return FindValue(ptr->leftchild, kx); } else if (kx > ptr->key) { return FindValue(ptr->rightchild, kx); } } //插入 bool Insert(BstNode* &root, KeyType kx) { if (root == NULL) { root = MakeRoot(kx); return true; } BstNode* pa = NULL; BstNode* p = root; // while (p != NULL && p->key != kx) { pa = p; p = kx < p->key ? p->leftchild : p->rightchild; } if (p != NULL && p->key == kx) return false; p = Buynode(); p->key = kx; if (p->key > pa->key) { pa->rightchild = p; } else { pa->leftchild = p; } return true; } int main() { BSTree root = NULL; // CreateTree(); int val; while (cin >> val, val != -1) { Insert(root, val); } InOrder(root); cout << endl; cin >> val; BstNode* pos = FindValue(root, val);//二叉搜索树的查询 return 0; }
怎样建立一个左右子树高度差不超过一(以二分查询方式创建二叉树)
void InOrder(BstNode* ptr) { if (ptr != NULL) { InOrder(ptr->leftchild); cout << ptr->key << " "; InOrder(ptr->rightchild); } } //递归二叉树 BstNode* CreateBST(const KeyType* ar, int left, int right) { BstNode* s = NULL; if (left <= right) { int mid = (right + left) / 2; s = Buynode(); s->key = ar[mid]; s->leftchild = CreateBST(ar, left, mid - 1); s->rightchild = CreateBST(ar, mid + 1, right); } return s; } int main() { int ar[] = { 12,23,34,45,56,67,78,89,90,100 }; int n = sizeof(ar) / sizeof(ar[0]); BSTree root = CreateBST(ar, 0, n - 1); InOrder(root); cout << endl; return 0; }
对数组里面存在的二叉树进行中序遍历
BstNode * ArInOrder(const int* ar, int i, int n) { BstNode* s = NULL; if (i < n && ar[i] != -1) { cout << ar[i] << " "; ArInOrder(ar, i * 2 + 1, n); // left ArInOrder(ar, i * 2 + 2, n);// right; } return s; } int main() { int ar[] = { 31,23,12,66,-1,5,17,70,62,-1,-1,-1,88,-1,55 }; int n = sizeof(ar) / sizeof(ar[0]); ArInOrder(ar, 0, n); return 0; }
排序二叉树的删除(BST)
//删除 bool Remvoe(BstNode*& ptr, KeyType kx) //指针的引用ptr可改变 { if (ptr == NULL) return false; BstNode* pa = NULL; BstNode* p = ptr; // root; while (p != NULL && p->key != kx) { pa = p; p = kx < p->key ? p->leftchild : p->rightchild; } if (p == NULL) return false; if (p->leftchild != NULL && p->rightchild != NULL) { BstNode* q = p->rightchild; pa = p; while (q->leftchild != NULL) { pa = q; q = q->leftchild; } p->key = q->key; p = q; } // BstNode* child = p->leftchild != NULL ? p->leftchild : p->rightchild; if (pa == NULL) { ptr = child; //newroot; } else { if (pa->leftchild == p) { pa->leftchild = child; } else { pa->rightchild = child; } } Freenode(p); return true; } int main() { BSTree root = NULL; // Remove(root); }
AVL树
一颗AVL树或者是空树,或者具有下列二叉搜索树:它的左子树和右子树都是AVL树,且左子树和右子树的高度之差的绝对值不超过1
AVL树的旋转
左单旋转
void RotateLeft(AVLNode*& ptr) { AVLNode* newroot = ptr->rightchild; newroot->parent = ptr->parent; // 1 改变第一个双亲 ptr->rightchild = newroot->leftchild; if (newroot->leftchild != NULL) { newroot->leftchild->parent = ptr; //2 改变第二个双亲 } newroot->leftchild = ptr; ptr->parent = newroot; // 3 改变第三个双亲 ptr = newroot; }
右单旋转
void RotateRight(AVLNode*& ptr) { AVLNode* newroot = ptr->leftchild; newroot->parent = ptr->parent; ptr->leftchild = newroot->rightchild; if (newroot->rightchild != NULL) { newroot->rightchild->parent = ptr; } newroot->rightchild = ptr; ptr->parent = newroot; ptr = newroot; }
先左后右双循环
对左边做平衡
对右边做平衡
//先左后右双循环 void LeftBalance(AVLNode*& ptr) { AVLNode* leftsub = ptr->leftchild, * rightsub = NULL; switch (leftsub->balance) { case 0: cout << "left sub tree balance \n" << endl; break;//平衡 case -1://进行右单旋 ptr->balance = 0; leftsub->balance = 0; RotateRight(ptr); break; case 1: rightsub = leftsub->rightchild; switch (rightsub->balance) { case 0: ptr->balance = 0; leftsub->balance = 0; break; case 1: ptr->balance = 0; leftsub->balance = -1; break; case -1: ptr->balance = 1; leftsub->balance = 0; break; } rightsub->balance = 0; RotateLeft(ptr->leftchild); RotateRight(ptr); break; } } void RightBalance(AVLNode*& ptr) { AVLNode* rightsub = ptr->rightchild, * leftsub = NULL; switch (rightsub->balance) { case 0: cout << "right sub balance " << endl; break; case 1: ptr->balance = 0; rightsub->balance = 0; RotateLeft(ptr); break; case -1: leftsub = rightsub->leftchild; switch (leftsub->balance) { case 0: ptr->balance = 0; rightsub->balance = 0; break; case 1: ptr->balance = -1; rightsub->balance = 0; break; case -1: ptr->balance = 0; rightsub->balance = 1; break; } leftsub->balance = 0; RotateRight(ptr->rightchild); RotateLeft(ptr); break; } } void Adjust(AVLNode* child) { AVLNode* pa = child->parent; bool tall = true; while (tall && pa != NULL) { if (pa->leftchild == child) { switch (pa->balance) { case 0: pa->balance = -1; break; case 1: pa->balance = 0; tall = false; break; case -1: LeftBalance(pa); tall = false; break; } } else { switch (pa->balance) { case 0: pa->balance = 1; break; case -1: pa->balance = 0; tall = false; break; case 1: RightBalance(pa); tall = false; break; } } child = pa; pa = child->parent; } } bool InsertItem(AVLNode*& root,KeyType kx) { if (root == NULL) { root = MakeRoot(kx); return true; } // // Adjust(p); } int main() { return 0; }
红黑树
红黑树的插入和调整
typedef enum { RED = 0, BLACK = 1 } ColorType; typedef int KeyType; typedef struct rb_node { struct rb_node* leftchild; struct rb_node* parent; struct rb_node* rightchild; ColorType color; // 0 1 KeyType key; }rb_node; typedef struct { rb_node* head; rb_node* _Nil; int cursize;//数据结点个数 }RBTree; rb_node* Buynode(ColorType color = RED) { rb_node* s = (rb_node*)malloc(sizeof(rb_node)); if (NULL == s) exit(1); memset(s, 0, sizeof(rb_node)); s->color = RED; return s; } void InitRBTree(RBTree* ptree) { assert(ptree != NULL); ptree->cursize = 0; ptree->head = Buynode(); ptree->_Nil = Buynode(BLACK); ptree->head->parent = ptree->_Nil; } //插入(带头结点和哨兵结点) //左旋 void RotateLeft(RBTree* ptree, rb_node * ptr) { rb_node* newroot = ptr->rightchild; newroot->parent = ptr->parent; // 1 ptr->rightchild = newroot->leftchild; if (newroot->leftchild != ptree->_Nil) { newroot->leftchild->parent = ptr; // 2 } newroot->leftchild = ptr; if (ptr->parent == ptree->head) { ptree->head->parent = newroot; } else { if (ptr->parent->rightchild == ptr) { ptr->parent->rightchild = newroot; } else { ptr->parent->leftchild = newroot; } } ptr->parent = newroot; // 3 } //右旋 void RotateRight(RBTree* ptree, rb_node* ptr) { rb_node* newroot = ptr->leftchild; newroot->parent = ptr->parent; //1 ptr->leftchild = newroot->rightchild; if (newroot->rightchild != ptree->_Nil)//如果不是一个哨兵结点 { newroot->rightchild->parent = ptr; } newroot->rightchild = ptr; if (ptr->parent == ptree->head) { ptree->head->parent = newroot; } else { if (ptr->parent->leftchild == ptr) { ptr->parent->leftchild = newroot; } else { ptr->parent->rightchild = newroot; } } ptr->parent = newroot; } //调整 void Adjust(RBTree *ptree, rb_node *p) { rb_node* pa = p->parent; while (pa != ptree->head->parent && pa->color == RED) // ? { if (p->parent->parent->rightchild == p->parent) // right { rb_node *_Y = p->parent->parent->leftchild; if (_Y->color == RED) { _Y->color = BLACK; p->parent->color = BLACK; p->parent->parent->color = RED; p = p->parent->parent; } else { if (p->parent->leftchild == p) { p = p->parent; RotateRight(ptree, p); } p->parent->color = BLACK; p->parent->parent->color = RED; RotateLeft(ptree, p->parent->parent); } } else //left { rb_node* _Y = p->parent->parent->rightchild; if (_Y->color == RED) { _Y->color = BLACK; p->parent->color = BLACK; p->parent->parent->color = RED; p = p->parent->parent; } else { if (p->parent->rightchild == p) { p = p->parent; RotateLeft(ptree, p); } p->parent->color = BLACK; p->parent->parent->color = RED; RotateRight(ptree, p->parent->parent); } } pa = p->parent; } ptree->head->parent->color = BLACK; } void InsertItem(RBTree* ptree) { Adjust(ptree, p); } int main() { RBTree myt; InitRBTree(&myt); }