排序二叉树
二叉树:作为基本数据结构的一种,是红黑树,B树等树形结构的基础。而排序二叉树是按照二叉树的结构来组织的。在本文中采用链表结构来创建二叉树。排序二叉树的 基本原理:
排序二叉树是将归并排序的基本思想构建二叉树结构,再用中序遍历的规则来遍历树的各个节点,输出的结果就是有序序列(本文是将一组无序的整型数值存储在二叉树中,通过中序遍历二叉树将数值输入,而得到一组按照由小到大排序的序列,从而间接实现了排序。所以下文的解释和说明都以此为例)。
插入节点的过程:
1.判断根节点是否为空?如果为空,插入节点作为根节点,结束;否则,转2;
2.将要插入的数值和比较节点的数值进行比较。如果插入插入数值大于等于节点数值转3;否则转4;
3.如果比较节点的右子树为空,将比较节点的右指针指向插入节点,结束;否则,将比较节点的右子树的根节点作为新的比较节点,转2;
4.如果比较节点的左子树为空,将比较节点的左指针指向插入节点,结束;否则,将比较节点的左子树的根节点作为新的比较节点,转2;
通过上述的插入过程实现的二叉树,可以得出:对于根节点,它左边的所有节点的值都小于它;而它右边的所有节点是数字都大于或等于它。中序遍历的过程是“左子节点->父节点->右子节点” ,这样数值的输出便具有了一定的顺序,这个规则的不断重复,就是归并排序思想的体现。同时该插入过程符合递归的特性。
算法分析(时间复杂度):
查找过程:二叉树查找过程的时间和二叉树的高度成正比。假设二叉树的高度为n,则查找最大值,最小值,前继结点后和后继节点的时间都可以在O(n)时间内实现。所以树的高度直接决定查找的效率。对于拥有n个节点的二叉树,形成完全二叉树时树的高度是最小的,即最小为lg(n);
删除和插入过程:在二叉树删除和插入过程,查找过程是必须的前奏;所以插入和删除的最小为(lg(n)+O(1)),其中O(1)为插入和删除的时间。
1 #include "stdafx.h" 2 #include <stdio.h> 3 #include <stdlib.h> 4 5 //非递归方法插入节点 6 void InsertBtree(node *root,int value) 7 { 8 9 node *t=(node *)malloc(sizeof(node)); 10 t->left=t->right=NULL; 11 t->number=value; 12 13 node *temp=NULL; 14 temp=root; 15 16 if(temp==NULL) 17 { 18 root=t; 19 } 20 else 21 { 22 while(temp!=NULL) 23 { 24 if(t->number>=temp->number) 25 { 26 if(temp->right==NULL) 27 { 28 temp->right=t; 29 break; 30 } 31 else 32 { 33 temp=temp->right; 34 } 35 36 } 37 else 38 { 39 if(temp->left==NULL) 40 { 41 temp->left=t; 42 break; 43 } 44 else 45 { 46 temp=temp->left; 47 } 48 } 49 } 50 } 51 } 52 53 //采用递归的方法插入节点 54 void InsertBtreeRe(node *root,int value) 55 { 56 if(root==NULL) 57 { 58 59 root->number=value; 60 return; 61 } 62 else 63 { 64 if(value>=root->number) 65 { 66 if(root->right==NULL) 67 { 68 node *roott=(node *)malloc(sizeof(node)); 69 roott->left=roott->right=NULL; 70 roott->number=value; 71 root->right=roott; 72 return; 73 } 74 else 75 { 76 InsertBtreeRe(root->right,value); 77 } 78 } 79 else 80 { 81 if(root->right==NULL) 82 { 83 node *roott=(node *)malloc(sizeof(node)); 84 roott->left=roott->right=NULL; 85 roott->number=value; 86 root->left=roott; 87 return; 88 } 89 else 90 { 91 InsertBtreeRe(root->left,value); 92 } 93 } 94 } 95 } 96 97 98 //将一个整数数组中的数字按照归并排序的原理进行存储 99 void buildBtree(int *p, int n,node *root) 100 { 101 int i; 102 node *vp=NULL; 103 104 root->number=p[0]; 105 root->left=root->right=NULL; 106 107 for(i=1;i<n;i++) 108 { 109 110 vp=root; 111 node *temp=(node *)malloc(sizeof(node)); 112 temp->number=p[i]; 113 temp->left=temp->right=NULL; 114 115 while(vp!=NULL) 116 { 117 if(temp->number>=vp->number) 118 { 119 if(vp->right==NULL) 120 { 121 vp->right=temp; 122 break; 123 } 124 else 125 { 126 vp=vp->right; 127 } 128 } 129 else 130 { 131 if(vp->left==NULL) 132 { 133 vp->left=temp; 134 break; 135 } 136 else 137 { 138 vp=vp->left; 139 } 140 } 141 } 142 143 } 144 145 } 146 147 //按照中序遍历二叉树 148 void midsearchBtree(node *proot) 149 { 150 if(proot!=NULL) 151 { 152 midsearchBtree(proot->left); 153 printf("%d ",proot->number); 154 midsearchBtree(proot->right); 155 } 156 } 157 158 int main() 159 { 160 node *croot; 161 int input; 162 croot=(node *)malloc(sizeof(node)); 163 164 int a[]={7,5,3,2,4}; 165 buildBtree(a,5,croot); 166 midsearchBtree(croot); 167 printf("\n"); 168 169 while(scanf_s("%d",&input)&& input!=1) 170 { 171 InsertBtree(croot,input); 172 } 173 midsearchBtree(croot); 174 printf("\n"); 175 176 InsertBtreeRe(croot,10); 177 midsearchBtree(croot); 178 printf("\n"); 179 return 0; 180 }