二叉排序树
2015-06-02 17:37
127 查看
该博客通过代码来展示对二叉排序树的各种操作:
#include<stdio.h> #include<stdlib.h> typedef int KeyType; typedef struct Node { KeyType key;//关键字 struct Node *left;//左孩子指针 struct Node *right;//右孩子指针 struct Node *parent;//指向父亲节点的指针 }Node,*PNode; /* *往二叉排序树中插入节点 *插入的话,可能要改变根节点的地址,所以传的是二级指针 */ void insert(PNode *root,KeyType key) { //初始化插入节点 PNode p=(PNode)malloc(sizeof(Node)); p->key=key; p->left=p->right=p->parent=NULL; //空树时,直接作为根节点 if((*root)==NULL) { *root=p; return ; } //插入到当前节点的左孩子 if((*root)->left==NULL&&(*root)->key>key) { p->parent=(*root); (*root)->left=p; return ; } //插入到当前节点的右孩子 if((*root)->right==NULL&&(*root)->key<key) { p->parent=(*root); (*root)->right=p; return ; } if((*root)->key>key) { insert(&(*root)->left,key); } else if((*root)->key<key) insert(&(*root)->right,key); else return; } //查找元素,找到返回关键字的结点指针,没有找到返回NULL PNode search(PNode root,KeyType key) { if(root==NULL) return NULL; if(key>root->key)//查找右子树 return search(root->right,key); else if(key<root->key)//查找左子树 return search(root->left,key); else return root; //查找最小关键字。空树时返回NULL PNode searchMin(PNode root) { if(root==NULL) return NULL; if(root->left==NULL) return root; else //一直往左孩子找 return searchMin(root->left); } //查找最大关键字,空树时返回NULL PNode searchMax(PNode root) { if(root==NULL) return NULL; if(root->right==NULL) return root; else //一直往右孩子找 return searchMax(root->right); } /* *根据关键字删除某个结点,删除成功返回1,否则返回0; *如果把结点删掉,那么要改变根节点的地址,所以传二级指针 */ int deleteNode(PNode *root,KeyType key) { PNode q; //查找要删除的结点 PNode p=search(*root,key); KeyType temp;//暂存后继结点的值 if(!p) return 0; //1.被删的结点是叶子结点,直接删除 if(p->left==NULL&&p->right==NULL) { //只有一个元素,删完后变成空树 if(p->parent==NULL) { free(p); (*root)=NULL: } else{ if(p->parent->left==p) p->parent->left=NULL; else p->parent->right=NULL; free(p); } } //2.被删除的结点只有左子树 else if(p->left&&!(p->right)) { p->left->parent=p->parent; if(p->parent==NULL) *root=p->left; else if(p->parent->left==p) p->parent->left=p->left; else p->parent->right=p->left; free(p); } //3.被删除的结点只有右孩子 else if(p->right&&!(p->left)) { p->right->parent=p->parent; //如果删除是父结点,要改变父节点指针 if(p->parent == NULL) *root=p->right; //删除的结点是父节点的左孩子 else if(p->parent->left == p) p->parent->left=p->right; else //删除的结点是父节点的右孩子 p->parent->right=p->right; free(p); } //4.被删除的结点既有左孩子,又有右孩子 //该结点的后继结点肯定无左子树(参考上面查找后继结点函数) //删掉后继结点,后继结点的值代替该结点 else{ //找到要删除结点的后继 q=searchSuccessor(p); temp=q->key; //删除后继结点 deleteNode(root,q->key); p->key=temp; } return 1; } //创建一棵二叉排序树 void create(PNode *root,KeyType *keyArray,int length) { int i; for(i=0;i<length;i++) insert(root,keyArray[i]); } int main(void) { int i; PNode root=NULL; KeyType nodeArray[11]={15,6,18,3,7,17,20,2,4,13,9}; create(&root,nodeArray,11); for(i=0;i<2;i++) deleteNode(&root,nodeArray[i]); printf("%d\n",searchMin(root)->key); printf("%d\n",searchMax(root)->key); printf("%d\n",search(root,13)->key); return 0; } }
相关文章推荐
- 清除xcode里面的mobileprovision文件
- 了解iOS上的可执行文件和Mach-O格式
- 构建、测试和部署驱动程序
- Jenkins入门总结
- cocos2dx 自定义menu 添加到scrollview上可以滑动
- difference of top and left between Javascript and Jquery
- 各种查找算法
- python实例
- nginx双向链表ngx_queue_t
- Active Directory 2003升级至2012(Part1)
- 安装VirtualBox出错提示Unable to load R3 module ...VBoxDD.dll (VBoxDD):GetLastError=1790
- Android大图片裁剪终极解决方案(上:原理分析)
- 5.1.4 Binary Tree Inorder Traversal
- 3.机器学习的各个角度
- android:layout_gravity和android:gravity的区别
- This和super之间的关系和区别
- MSSQL - 备份和还原数据库
- 创建sharepoint网站
- Android实现简单的倒计时功能
- OTG驱动分析(二)