1.首先是二叉排序树的结构定义,一个数据域,另外两个是指针域,一个指向左孩子,另外一个指向右孩子。
//二叉排序树的结构定义 typedef struct Node{ int data; struct Node *lchild,*rchild; }TreeNode,*BSTree;
2.在二叉排序树中查找关键字为k的节点,这里用while循环实现迭代查找,如果找到返回节点指针,没有找到返回NULL。
//查找,成功返回节点指针,失败返回NULL。 BSTree BSTreeSeach(BSTree T,int k){ TreeNode *p; p = T; while(p!=NULL){ if(k==p->data){ return p; }else if(k<p->data){ p = p->lchild; }else{ p = p->rchild; } } return NULL; }
3.插入操作,如果已经存在相同的节点,则插入失败,直接返回。用parent表示待插入节点的双亲节点。然后开辟一个内存空间p,存放待插入的节点;如果parent为空,则说明树为空,直接将p赋值给parent;否则根据插入值k大小将p设置为parent的子节点。
//插入操作 void InsertBSTree(BSTree *T,int k){ TreeNode *p,*cur,*parent=NULL; //当前指针 cur = *T; //树不为空 while(cur!=NULL){ if(cur->data==k){ printf("已存在的数据!"); return ; } //待插入节点的双亲节点 parent=cur; if(k<cur->data){ cur = cur->lchild; }else{ cur = cur->rchild; } } p = (BSTree)malloc(sizeof(TreeNode)); p->data = k; p->lchild = NULL; p->rchild = NULL; if(!parent){ *T = p; }else if(k<parent->data){ parent->lchild = p; }else{ parent->rchild =p; } }
4.删除操作,假设删除节点为s,这里有三种情况:
1.s的左子树为空,用s的右子树来覆盖s;
2.s的右子树为空,用s的左子树来覆盖s,若s的左子树也为空,也相当于情况1;
3.s的左右子树都不为空,此时将s的右子树连接到s的左子树的最大节点的右孩子节点上,然后用s的左子树覆盖s;
//删除操操作 void BSTDelete(BSTree *s){ TreeNode *temp=NULL; if((*s)->rchild==NULL){ temp = *s; *s = (*s)->lchild; free(temp); }else if((*s)->lchild==NULL){ temp = *s; *s = (*s)->rchild; free(temp); }else{ for(temp=(*s)->lchild;temp->rchild!=NULL;temp=temp->rchild){ continue; } temp->rchild = (*s)->rchild; temp = *s; *s = (*s)->lchild; free(temp); } }
4.遍历操作,用递归实现很简单,这里是中序遍历。
//中序遍历 void LDRBSTree(BSTree T){ if(T){ LDRBSTree(T->lchild); printf("%d ",T->data); LDRBSTree(T->rchild); } }
下面是测试代码:
int main(void){ int a[]={37,32,35,62,82,95,73,12,5,99}; int i,n; BSTree Tree=NULL; n = sizeof(a)/sizeof(a[0]); //构造二叉排序树 for(i=0;i<n;i++){ InsertBSTree(&Tree,a[i]); } printf("中序遍历:"); LDRBSTree(Tree);
return 0; }