Tree
Created|Updated
|Post Views:
二叉树
二叉树是树的一种,每个节点最多只能有两个孩子。
树型结构是一种逻辑结构,他们同样可以用顺序结构和链式结构来实现。
结构
1 2 3 4 5 6 7
| typedef char BiElemType; typedef struct BiTNode { BiElemType c; struct BiTNode* lchild; struct BiTNode* rchild; }BiTNode, * BiTree;
|
层序建树
这里要用到一个辅助链表(不带头节点)。它将记录一个个节点,一层层,插入到树中的顺序。
流程图

代码实现
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 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72
| #include"Header.h"
void PreOrder(BiTree p) { if (p != NULL) { putchar(p->c); PreOrder(p->lchild); PreOrder(p->rchild); } }
void InOrder(BiTree p) { if (p != NULL) { InOrder(p->lchild); putchar(p->c); InOrder(p->rchild); } }
void PostOrder(BiTree p) { if (p != NULL) { PostOrder(p->lchild); PostOrder(p->rchild); putchar(p->c); } }
int main() { BiTree pnew; char c; BiTree tree = NULL; ptag_t phead = NULL, ptail = NULL, listpnew=NULL, pcur=NULL; while (scanf("%c", &c) != EOF) { if (c == '\n') { break; } pnew = (BiTree)calloc(1, sizeof(BiTNode)); pnew->c = c; listpnew = (ptag_t)calloc(1, sizeof(tag_t)); listpnew->p = pnew; if (NULL == tree) { tree = pnew; phead = listpnew; ptail = listpnew; pcur = listpnew; continue; } else { ptail->pnext = listpnew; ptail = listpnew; } if (NULL == pcur->p->lchild) { pcur->p->lchild = pnew; } else if (NULL == pcur->p->rchild) { pcur->p->rchild = pnew; pcur = pcur->pnext; } } PreOrder(tree); printf("\n"); InOrder(tree); printf("\n"); PostOrder(tree); }
|
二叉树的遍历
层序遍历(广度优先遍历)
从上往下对每一层依次访问,在每一层中,从左往右(也可以从右往左)访问结点,访问完一层就进入下一层,直到没有结点可以访问为止。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18
| void levelOrder(BiTree tree) { LinkQueue lq; InitQueue(lq); EnQueue(lq, tree);
BiTree p; while (!QueueEmpty(lq)) { DeQueue(lq, p); printf("%c", p->c); if (p->lchild) { EnQueue(lq, p->lchild); } if (p->rchild) { EnQueue(lq, p->rchild); } } }
|
深度优先遍历
对每一个可能的分支路径深入到不能再深入为止,而且每个结点只能访问一次。
先序遍历
1 2 3 4 5 6 7
| void PreOrder(BiTree p) { if (p != NULL) { putchar(p->c); PreOrder(p->lchild); PreOrder(p->rchild); } }
|
中序遍历
1 2 3 4 5 6 7
| void InOrder(BiTree p) { if (p != NULL) { InOrder(p->lchild); putchar(p->c); InOrder(p->rchild); } }
|
后序遍历
1 2 3 4 5 6 7
| void PostOrder(BiTree p) { if (p != NULL) { PostOrder(p->lchild); PostOrder(p->rchild); putchar(p->c); } }
|
线索二叉树
它建立在二叉树的基础之上,分为前序,中序后序线索二叉树。线索化的时候,根据前序,中序,后序遍历的顺序形成一个链表。
如果lchild==NULL,那么指向前驱节点,ltag=1;否则ltag=0;
如果rchild==NULL,那么让指向后继节点,rtag=1;否则rtag=0;

二叉排序树(二叉查找树)(Binary Search Tree)
注意:这里要理解递归的思想。递归的思想就是二叉树的思想,
先把二叉树看成只有1个根,1个左孩子,1个右孩子构成(递归的第一层)。
接下来,又把左孩子看成根,根和根的左右孩子,他们3个又组成一颗树。(递归的第二层)。
又把右孩子看成根,根和根的左右孩子,他们3个又组成一颗树。(递归的第三层)。
结束条件:如果左孩子或者右孩子为空。
重复2,3的过程,这样整颗树就遍历完成
BST的三原则
- 左子树的所有节点要比根小
- 右子树的所有节点要比根大
- 左子树右子树又可以是一颗二叉排序树
BST的创建
流程图
代码实现
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
| typedef int BiElemType ;
typedef struct BiTNode { BiElemType data; struct BiTNode* lchild; struct BiTNode* rchild; }BiTNode,*BiTree;
bool Insert_BST(BiTree& t, BiElemType e) { if (NULL == t) { t = (BiTree)calloc(1, sizeof(BiTNode)); t->data = e; return true; } else if (e == t->data) { return false; } else if (e < t->data) { return Insert_BST(t->lchild, e); } else { return Insert_BST(t->rchild, e); } }
void Create_BST(BiTree &t, BiElemType *arr, int n) { for (size_t i = 0; i < n; i++) { Insert_BST(t, arr[i]); } }
|
BST的查找(折半查找)
因为二叉查找树是有序的,所以,我们可以用折半查找的方法,可以提高查找效率。BST的查找次数最多只是树的高度。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17
| int Binary_Search(ElemType e, ElemType* arr, int n) { int low = 0, high=n-1, mid; while (low <= high) { mid = (low + high) / 2; if (arr[mid] == e) { return mid; } else if (e < arr[mid]) { high = mid - 1; } else { low = mid + 1; } } }
|