算法基础(七):二叉排序树基本操作-插入、删除(附源代码加注释)
2014-03-11 21:01
423 查看
#include"stdafx.h" #include"Basic_Symbol.h" #define MaxSize 100 typedef int KeyType; //定义关键字类型 typedef char InfoType; typedef struct node //定义结点类型 { KeyType key; //关键字项 InfoType data; //数据域 struct node *lchild, *rchild; //左右孩子指针 }BSTNode; //全局变量 KeyType predt = -32767; //保存中序节点前驱的值 int path[MaxSize]; //全局变量,用于存放路径 void DispBST(BSTNode *b); //函数声明 int InsertBST(BSTNode *&p, KeyType k) //P为根节点,插入关键字为K的结点 { if( p == NULL) //如果原树为空,则操作 { p = (BSTNode *)malloc(sizeof(BSTNode)); //分配空间 p->key = k; p->lchild = p->rchild = NULL; //左右孩子初值为空 return 1; } else if(k == p->key) //如果等于,则return,因为二叉排序树里面不会有两个相等的数字 return 0; else if(k < p->key) //如果小于,则放左边,要深刻理解递归,代码便写的自然 return InsertBST(p->lchild,k); else return InsertBST(p->rchild,k); //大于,放右边,满足二叉排序树的特点 } BSTNode *CreatBST(KeyType A[],int n) //利用数组A中的元素作为关键字来构造二叉树,n为要建立的结点个数,应小于数组长度 { BSTNode *bt = NULL; int i = 0; while(i< n) //循环加递归构造二叉排序树 if(InsertBST(bt,A[i]) == 1) { printf("\nthe number %d step:",i+1,A[i]); DispBST(bt); i++; } return bt; //返回根指针 } void Delete1(BSTNode *p,BSTNode *&r) //当被删除结点p有左右子树时的删除过程 { BSTNode *q; if(r->rchild != NULL) //如果右孩子不为空 { Delete1(p,r->rchild); //递归找到最右下节点,为什么要找最右下节点了,因为最右下节点是这棵树中最大的。 } else //找到了最右下 { p->key = r->key; //将r的关键字赋值给p,这是必须的,只有r的关键字(x)可以来胜任..x是左边的树中最大的但是小于p->key,更小于p的右子树。 q = r; r = r->lchild; //r的值被r左孩子代替 free(q); //释放空间 } } void Delete( BSTNode *&p) //从二叉排序树中删除*p结点,这是在已经找到了要删除的节点时调用的,在DeleteBST中被调用 { BSTNode *q; if(p->rchild == NULL) //没有右子树的情况 { q = p; p = p->lchild; //p指向的内存空间被释放,显然此时p退居到左孩子位置,哈哈!画个图图看看更清晰哈 free(q); } else if(p->lchild == NULL) //没有左子树,同样的道理.. { q = p; p = p->rchild; free(q); } else Delete1(p,p->lchild); //左右都有的话,调用DELETE1函数来处理该情况 } int DeleteBST(BSTNode *&bt,KeyType k) //在bt中删除关键字为k的结点 { if(bt == NULL) return 0; //空树,删除失败 else { if(k < bt->key) return DeleteBST(bt->lchild,k); else if(k>bt->key) return DeleteBST(bt->rchild,k); else { Delete(bt); return 1; } } } void SearchBST1(BSTNode *bt,KeyType k,KeyType path[],int i) //以非递归方式输出路径 { int j; if(bt == NULL) return; else if(k == bt->key) //找到了 { path[i+1] = bt->key; //将节点的值保存在路径中 for(j = 0;j<=i+1;j++) printf("%3d",path[j]); //输出 printf("\n"); } else //没找到 { path[i + 1] = bt->key; //将节点的值保存在路径中,下面更具情况继续找 if(k < bt->key) //如果k小于当前值 SearchBST1(bt->lchild,k,path,i+1); //则进入左子树找,这是根据二叉排序树的特点来的 else SearchBST1(bt->rchild,k,path,i+1); //大的话。进入右边找。其实找,还是在递归,只是把路径保存在一个可爱的数组中而已 } } int SearchBST2(BSTNode *bt,KeyType k) //递归输出路径,就要简单的多了,但是理解不是很容易,递归太重要了,对吧! { if(bt == NULL) return 0; else if(k == bt->key) { printf("%3d",bt->key); return 1; } else if(k < bt->key) SearchBST2(bt->lchild,k); else SearchBST2(bt->rchild,k); printf("%3d",bt->key); } void DispBST(BSTNode *bt) //括号表示法输出二叉排序树 { if(bt != NULL) { printf("%d",bt->key); //输出根节点的值 if(bt->lchild != NULL || bt->rchild != NULL) //如果左右孩子不为空,输出他们的key值 { printf("("); DispBST(bt->lchild); if(bt->rchild != NULL) printf(","); DispBST(bt->rchild); printf(")"); } } } int JudgeBST(BSTNode *bt) //判断是否是二叉排序树 { int b1,b2; if(bt == NULL) //空则返回 return 1; else { b1 = JudgeBST(bt->lchild); //递归得到最左下的节点 if(b1 == 0 || predt >= bt->key) //如果左边的值比其父节点的key大,则不是二叉排序树,返回0,如果父节点的key大于右边的key,则返回0 return 0; predt = bt->key; //依次得到key值,注意这个语句的位置,pre的得到是按照左到右的顺序 printf("\npredt = %d",predt); b2 = JudgeBST(bt->rchild); //判断右边 return b2; } } /* 总结:我觉得数据结构,最重要的是它的思想,真的是非常的精妙。 像《树》这章,树的层次结构首先我们要清晰,然后就是深刻理解递归的思想,这又牵扯到栈的知识。 */ void main() { BSTNode *bt; KeyType k = 6; //后面要寻找带这个关键字的节点 int n = 10; //数组元素个数 int a[] = {4,9,0,1,8,6,3,5,2,7}; printf("create a BST Tree:\n"); bt = CreatBST(a,n); printf("BST:\n"); DispBST(bt); printf("\n"); printf("bt%s\n",(JudgeBST(bt)?"yes,it is a bst":"no,it is not a bst")); printf("\n"); printf("\nsearch the keyword(di gui) : %d",k); SearchBST1(bt,k,path, -1); printf("\nsearch the keyword(not di gui) : %d",k); printf("\ndelete..."); printf("\nthe origin BST:"); DispBST(bt); printf("\n delete the node 4.."); DeleteBST(bt,4); DispBST(bt); printf("\n delete the node 5.."); DeleteBST(bt,5); DispBST(bt); printf("\n"); }
相关文章推荐
- 数据结构基础5.2:二叉搜索树(BST)的基本操作(插入、查找、删除)
- 线性表的基本操作:插入、删除、查找等操作在顺序存储结构和链接存储结构上的算法
- 二叉排序树的基本操作(建立,中序遍历,查找,删除,插入)
- 数据结构基础5.4:堆(HEAP)的基本操作(插入与删除)
- 编程菜鸟的日记-初学尝试编程-顺序表的类定义及其基本操作算法(创建表、元素插入、元素删除、顺序查找、测表空、求表长、输出等)
- 二叉排序树--查询--插入--删除操作
- 链表的基本操作(插入,删除,排序、逆置等)
- bzoj 1208 splay基本操作(插入,查询,删除)
- 试用多态实现线性表(队列,串,堆栈),要求具备线性表的基本操作:插入,删除,测长等。
- 数据结构 线性链表的创立及其基本操作初始化、遍历、销毁、判空、求表长、删除、插入等
- 基础--JAVA对Mysql进行连接、插入、修改、删除操作
- 数据结构的一些基本操作(在表L中插入第i个元素e. 操作成功返回OK,失败时返回ERROR,删除表L中第i个元素,结果用e返回. 操作成功返回OK,失败时返回ERROR)
- FormView 显示、更新、插入、删除数据库操作[ASP.NET源代码](二)
- 数据结构线性表之顺序表的基本操作插入、删除、遍历、初始化
- 一步一步复习数据结构和算法基础-二叉树基本操作
- SQL基础操作_4_表的插入、更新、删除、合并操作
- 关于链表结构的基本操作 c 实现 (创建,插入删除,反转,合并链表,查找,是否有环,链表相交情况)
- 二叉排序树的删除操作 - 数据结构和算法75
- 单链表的基本操作的实现(建立、插入、删除、逆序)
- 链表的基础操作总结(链表创建,插入,删除,遍历等等)