树
1 #ifndef _Tree_H 2 struct TreeNode; 3 typedef struct TreeNode *Position; 4 typedef Struct TreeNode *SearchTree; 5 6 SearchTree MakeEmpty(Search T); 7 Position Find(ElemtntType X,SearchTree T); 8 Position FindMin(SearchTree T); 9 Position FindMax(SearchTree T); 10 SearchTree Insert(ElementType X,SearchTree T); 11 SearchTree Delete(ElementType X,SearchTree T); 12 ElementType Retrieve(Position P); 13 14 struct TreeNode 15 { 16 ElementType Element; 17 SearchTree Left; 18 SearchTree Right; 19 }; 20 21 //建立一个空二叉树 22 23 SearchTree MakeEmpty(SearchTree T) 24 { 25 if(T!=Null) 26 { 27 MakeEmpty(T->left); 28 MakeEmpty(T->Right); 29 free(T); 30 } 31 return NULL; 32 } 33 34 //二叉树的查找 35 Position Find(ElementType X,SearchTree T); 36 { 37 if(T==NULL) 38 return NULL; 39 if(X>T->Element) 40 return Find(X,T->Left); 41 else if(X<T->Element) 42 return Find(X,T->Right); 43 else return T; 44 } 45 46 //二叉查找树的FindMin递归实现 47 Position FindMin(SearchTree T) 48 { 49 if(NULL==T) 50 return NULL; 51 if(NULL==T->Left) 52 return T->Left; 53 else 54 return FindMin(T->Left); 55 } 56 //二叉查找树的FindMax的非递归实现 57 58 Position FindMax(SearchTree T) 59 { 60 if(NULL!=T) 61 while(NULL!=T->Right) 62 T=T->Right; 63 return T; 64 } 65 //插入元素到二叉查找树之中 66 SearchTree Insert(ElementType X,SearchTree T) 67 { 68 if(NULL==T) 69 { 70 T=malloc(sizeof(Strunt TreeNode)); 71 if(NULL==T) 72 FataErro("Out of Space! "); 73 else 74 { 75 T->Element=X; 76 T->Right=Null; 77 T->Left=NULL; 78 } 79 } 80 else if(X<T->Element) 81 Insert(X,X->Left); 82 else(X>T->Element) 83 Insert(X,X->Right); 84 //if X==T->Element,X has been T's element.We will do nothing. 85 return T; 86 } 87 //二叉查找树的删除,删除时有个节点转移的问题; 88 SearchTree Delete(ElementType X,SearchTree T) 89 { 90 Position PtrTmp; 91 if(NULL==T) 92 Erro("Element is not found"); 93 else if(X<T->Element)//if smaller, go left 94 Delete(X,T->Left); 95 else if(X>T->Element)//if bigger go right 96 Delete(X,T->Right); 97 else if(T->Riht&&T->Left)//Found it, the left and the right child trees both exist; 98 { 99 PtrTmp=FindMin(T->Right);//用右子树的最小的点替代被删除的元素 100 T->Element=PtrTmp->Element; 101 T->Right=Delete(T->Element,T->Right);//右子树为递归删除最小节点的改变后的节点 102 } 103 else//零个或者1个孩子的情况 104 { 105 PtrTmp=T; 106 if(NULL==T->Left) 107 T=T->Right; 108 else if(NULL=T->Right) 109 T=T->Left; 110 free(PtrTmp); 111 } 112 return T; 113 }
普通二叉树的缺点是 容易使树的左子树或者右子树深度失衡,从而查找的时间复杂度退化,从而引申出“平衡二叉树”(AVL树)
平衡二叉树(AVL树)关键是旋转来使其平衡;
伸展树:它保证从空树开始任意连续M次对树的操作最多花费O(MlogN)时间;但是这种保证不排除任意一次操作花费O(N)时间的可能;它可以保证不存在坏的输入队列;
树的遍历;
顺序打印二叉树的中序;
1 void PrintTree(SearchTree T) 2 { 3 if(NULL!=T) 4 { 5 PrintTree(T->Left); 6 PrintElement(T->Element); 7 PrintTree(T->Right); 8 } 9 }
使用后序遍历计算树的高度
1 int Height(Tree T) 2 { 3 if (NULL==T) 4 return -1; 5 else 6 return 1+Max(Height(T->Left),Height(T->Right)); 7 }
阶为M的B-树的定义:
1,树的根或者是一片树叶,或者其儿子在2和M之间;
2,除根外,所有非树叶节点的儿子树在¬M/2¬和M之间;
3, 所有的树叶都在相同的深度上;
所有的数据都存储在树叶上;
4阶的B-树更流行的称呼是2-3-4树,而3阶的B-树叫做2-3树;
B-树的深度最多是¬log¬m/2¬N¬
B-树在路径上的每个节点,执行O(logM)时间的工作量以确定选择哪个分支(使用折半查找),但是在Insert和Delete可能需要O(M)的工作量来调节点上的信息,对于每一个Insert和Delete,最坏的情形运行时间是
O(MlogMN)=O((M/logM)logN),对一次Find操作花费O(logN),经验指出:M=3或4运行时间最好,大于5之上没什么优势;
B-树实际运用于数据库系统,树被存储在硬盘而不是主存中,
在实践中,,所有平衡树方案的运行时间都不如简单二叉树查找树省时(差一个常数因子)但是可以接受,它防止轻易得到最坏情形的输入;;