二叉树的建立、节点查找以及节点删除C和C++实现

程序是建立一颗二叉排序树,查找节点找到了返回其父节点,失败的时候返回NULL,删除节点分为四种情况:1、左子树和右子树都为空;2、左子树为空,右子树不为空;3、左子树不为空,右子树为空;4、左子树和右子树都不为空。

C语言版本(利用结构体实现):

#include <stdio.h> #include <stdlib.h> typedef int DataType; typedef struct BTree{ DataType data; struct BTree *Tleft; struct BTree *Tright; }*BTree; BTree CreateTree(); //建树 BTree insert(BTree root, DataType data);//插入节点 void InBTree(BTree root); //中序遍历 void PreBTree(BTree root); //先序遍历 void PostBTree(BTree root);//后序遍历 BTree findPostion(BTree root, int deleteNode, int *flags);//寻找合适的插入点 BTree delNode(BTree root, BTree parent, int flags); //删除树节点 int main(){ BTree root = NULL; int flags = 0; int deleteNode = 0; BTree parent = NULL;//所删除节点的父节点 char choiceAgain = 'Y'; root = CreateTree(); printf("\n中序遍历: "); InBTree(root); printf("\n前序遍历: "); PreBTree(root); printf("\n后序遍历: "); PostBTree(root); printf("\n"); do{ printf("需要删掉的节点: "); scanf("%d", &deleteNode); parent = findPostion(root, deleteNode, &flags); root = delNode(root, parent, flags); printf("删除后的结果: "); printf("\n中序遍历: "); InBTree(root); printf("\n前序遍历: "); PreBTree(root); printf("\n后序遍历: "); PostBTree(root); choiceAgain = 'N'; printf("\nDelete Again(Y) or N?: "); getchar(); scanf("%c", &choiceAgain); }while(choiceAgain == 'Y' || choiceAgain == 'y'); printf("\nDone!\n"); return 0; } BTree CreateTree(){ BTree root = NULL; DataType temp = 0; printf("请输入节点,以0结尾:\n"); scanf("%d", &temp); while(temp != 0){ root = insert(root, temp); scanf("%d", &temp); } return root; } BTree insert(BTree root, DataType data){ BTree ptr = root; BTree tempNode; BTree newNode = (BTree)malloc(sizeof(struct BTree)); newNode->data = data ; newNode->Tleft = NULL; newNode->Tright = NULL; if(ptr == NULL){ return newNode; }else{ while(ptr != NULL){ tempNode = ptr; if(ptr->data >= data){ ptr = ptr->Tleft; }else{ ptr = ptr->Tright; } } if(tempNode->data >= data){ tempNode->Tleft = newNode; }else{ tempNode->Tright = newNode; } } return root; } BTree findPostion(BTree root, int deleteNode, int *flags){ BTree parentNode = root; BTree temp = root; *flags = 0; while(temp != NULL){ if(temp->data == deleteNode){ return parentNode; }else{ parentNode = temp; if(temp->data > deleteNode){ temp = temp->Tleft; *flags = -1; }else{ temp = temp->Tright; *flags = 1; } } } return NULL; } BTree delNode(BTree root, BTree parent, int flags){ BTree deleteNode = NULL; if(parent == NULL){ printf("未找到删除的节点!\n"); return root; } switch(flags){ case -1: deleteNode = parent->Tleft; break; case 0: deleteNode = parent; break; case 1: deleteNode = parent->Tright; break; default: printf("ERROR!\n"); exit(1); } if(deleteNode->Tleft == NULL && deleteNode->Tright == NULL){ if(parent->Tleft == deleteNode){ parent->Tleft = NULL; }else if(parent->Tright == deleteNode){ parent->Tright = NULL; }else{ parent = NULL; } free(deleteNode); }else if(deleteNode->Tleft == NULL && deleteNode->Tright != NULL){ if(deleteNode->data == root->data){ root = deleteNode->Tright; }else{ if(parent->Tleft->data == deleteNode->data){ parent->Tleft = deleteNode->Tright; }else{ parent->Tright = deleteNode->Tright; } } free(deleteNode); }else if(deleteNode->Tleft != NULL && deleteNode->Tright == NULL){ if(deleteNode->data == root->data){ root = deleteNode->Tleft; }else{ if(parent->Tleft->data == deleteNode->data){ parent->Tleft = deleteNode->Tleft; }else{ parent->Tright = deleteNode->Tleft; } } free(deleteNode); }else{ BTree temp = deleteNode->Tleft; BTree tempParent = deleteNode; while(temp->Tright != NULL){ tempParent = temp; temp = temp->Tright; } deleteNode->data = temp->data; if(tempParent->Tleft == temp){ tempParent->Tleft = temp->Tleft; }else{ tempParent->Tright = temp->Tleft; } printf("temp = %d\n", temp->data); free(temp); } return root; } void InBTree(BTree root){ if(root != NULL){ InBTree(root->Tleft); printf("%d ", root->data); InBTree(root->Tright); } } void PreBTree(BTree root){ if(root != NULL){ printf("%d ", root->data); PreBTree(root->Tleft); PreBTree(root->Tright); } } void PostBTree(BTree root){ if(root != NULL){ PostBTree(root->Tleft); PostBTree(root->Tright); printf("%d ", root->data); } }


C++版本(利用类实现)
#include <iostream.h> #include <cstring> typedef int KeyType; #define NUM 11 class BinStree; class BinSTreeNode { public: KeyType key; BinSTreeNode *lchild; BinSTreeNode *rchild; BinSTreeNode() { lchild = NULL; rchild = NULL; } }; class BinSTree { public: BinSTreeNode *root; BinSTree() { root = NULL; } ~BinSTree() { //delete root; } BinSTreeNode *BSTreeSearch( BinSTreeNode *bt, KeyType k, BinSTreeNode *&p ); void BSTreeInsert( BinSTreeNode *&bt, KeyType k ); int BSTreeDelete( BinSTreeNode *&bt, KeyType k ); void BSTreePreOrder(BinSTreeNode *bt); bool IsEmpty() { return root == NULL; } }; /** * 二叉树排序查找算法 * 在根指针为bt的二叉排序树中查找元素k的节点,若查找成功,则返回指向该节点的指针 * 参数p指向查找到的结点,否则返回空指针,参数p指向k应插入的父结点 */ BinSTreeNode* BinSTree::BSTreeSearch( BinSTreeNode *bt, KeyType k, BinSTreeNode *&p ) { BinSTreeNode *q = NULL; q = bt; while(q) { p = q; if( q->key == k ) { return(p); } if( q->key > k ) q = q->lchild; else q = q->rchild; } return NULL; } /** * 二叉排序树的插入节点算法 * bt指向二叉排序树的根结点,插入元素k的结点 */ void BinSTree::BSTreeInsert( BinSTreeNode *&bt, KeyType k ) { BinSTreeNode *p = NULL, *q; q = bt; if( BSTreeSearch( q, k, p ) == NULL ) { BinSTreeNode *r = new BinSTreeNode; r->key = k; r->lchild = r->rchild = NULL; if( q == NULL ) { bt = r; //被插入节点做为树的根节点 } if( p && k < p->key ) p->lchild = r; else if( p ) p->rchild = r; } } /** * 中序遍历 */ void BinSTree::BSTreePreOrder(BinSTreeNode *bt) { if(bt != NULL) { cout << bt->key << " "; BSTreePreOrder(bt->lchild); BSTreePreOrder(bt->rchild); } } /** * 二叉排序树的删除结点算法 * 在二叉排序树中删除元素为k的结点,*bt指向二叉排序树的根节点 * 删除成功返回1,不成功返回0. */ int BinSTree::BSTreeDelete( BinSTreeNode *&bt, KeyType k ) { BinSTreeNode *f, *p, *q, *s; p = bt; f = NULL; //查找关键字为k的结点,同时将此结点的双亲找出来 while( p && p->key != k ) { f = p; if( p->key > k ) p = p->lchild; else p = p->rchild; } if( p == NULL ) //找不到待删除的结点时返回 return 0; if( p->lchild == NULL ) //待删除结点的左子树为空 { if( f == NULL ) //待删除结点为根节点 bt = p->rchild; else if( f->lchild == p ) //待删结点是其双亲结点的左节点 f->lchild = p->rchild; else f->rchild = p->rchild; //待删结点是其双亲结点的右节点 delete p; } else //待删除结点有左子树 { q = p; s = p->lchild; while( s->rchild ) //在待删除结点的左子树中查找最右下结点 { q = s; s = s->rchild; } if( q == p ) q->lchild = s->lchild; else q->rchild = s->lchild; p->key = s->key; delete s; } return 1; } int main( void ) { int a[NUM] = { 34, 18, 76, 13, 52, 82, 16, 67, 58, 73, 72 }; int i; BinSTree bst; BinSTreeNode *pBt = NULL, *p = NULL, *pT = NULL; for( i = 0; i < NUM; i++ ) { bst.BSTreeInsert( pBt, a[i] ); //创建二叉排序树 } pT = bst.BSTreeSearch( pBt, 52, p ); //搜索排序二叉树 bst.BSTreePreOrder(pBt); cout << endl; bst.BSTreeDelete( pBt, 13 ); //删除无左孩子的情况 bst.BSTreePreOrder(pBt); cout << endl; bst.BSTreeDelete( pBt, 76 ); //删除有左孩子的情况 bst.BSTreePreOrder(pBt); cout << endl; return 0; }

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值