数据结构之二叉查找树的建立遍历删除
来源:互联网 发布:淘宝电商是什么 编辑:程序博客网 时间:2024/05/24 05:02
二叉查找树建立,遍历,查找元素很容易实现。我主要写写删除过程。
二叉查找树结点的删除分几种情况:
如果结点是一片树叶,那么直接删除即可。如果结点有一个儿子,则该节点可以在其父节点调整指针绕过该节点后被删除。如果结点有两个儿子,一般的删除方法是用其右子树的最小的数据代替该节点,并删除那个结点。因为最小的那个结点不可能有左儿子,所以第二次删除很容易实现。
代码如下,写的不太好,见笑了
#include<stdio.h>#include<stdlib.h>#include<string.h>typedef int DataType;typedef struct node{DataType data;struct node *lchild, *rchild;}BinTree, *Tree;// 添加结点Tree Add_New_Node(DataType data){Tree NewNode = (Tree)malloc(sizeof(BinTree));memset(NewNode, 0, sizeof(BinTree));NewNode->data = data;return NewNode;}// 二叉查找树的插入操作Tree Insert(Tree root, DataType num){if (root == NULL){root = Add_New_Node(num);}else if (num > root->data){root->rchild = Insert(root->rchild, num);}else if (num < root->data){root->lchild = Insert(root->lchild, num);}return root;}// 根据关键字找到该结点并返回该节点的地址Tree Find(Tree root, DataType key){if (root == NULL)return NULL;if (key < root->data)return Find(root->lchild, key);else if (key > root->data)return Find(root->rchild, key);elsereturn root;}// 在二叉查找树树中找到最小的结点的值(递归)Tree FindMin(Tree root){if (root == NULL)return NULL;if (root->lchild == NULL)return root;elsereturn FindMin(root->lchild);}// 在二叉查找树树中找到最大的结点的值(迭代)Tree FindMax(Tree root){if (root != NULL){while (root->rchild != NULL)root = root->rchild;}return root;}// 找到关键字的父节点并返回它本身的地址和父节点的地址,以及其左右子树对应关系Tree FindNodeAndPos(Tree root, DataType key, Tree *flag,int *sign){Tree p = root;if (p == NULL)return NULL;while (p != NULL){if (key < p->data){*sign = 1;*flag = p;p = p->lchild;}else if (key > p->data){*sign = 0;*flag = p;p = p->rchild;}elsereturn p;}return NULL;}// 删除的结点有1个或两个结点void Delete_A_Node_With_One_Child(Tree Parent,Tree Dest,int Pos){if (Parent == NULL || Dest == NULL)return;// 左子树为空右子树不为空if (Dest->lchild == NULL && Dest->rchild != NULL){if (1 == Pos)Parent->lchild = Dest->rchild;elseParent->rchild = Dest->rchild;}// 左子树不为空右子树为空else if (Dest->lchild != NULL && Dest->rchild == NULL){if (1 == Pos)Parent->lchild = Dest->lchild;elseParent->rchild = Dest->lchild;}// 左右子树均为空else{if (1 == Pos)Parent->lchild = NULL;elseParent->rchild = NULL;}free(Dest);}// 删除函数void Delete_Node_With_Pos(Tree root, DataType key){// Parent保存待删除结点的父节点的指针 Dest保存待删除节点的指针Tree Parent = NULL, Dest = NULL;// Pos标记待删除结点与它的父节点的左右关系,定义 '1'为左 '0'为右int Pos = 0;// 当待删除的结点为根节点时if (root->data == key){// Cur保存当前结点的地址 temp保存当前结点右子树中最小的结点的地址Tree Cur = Dest, temp = FindMin(root->rchild);// 右子树删完了再删左子树if (root->rchild!=NULL)temp = FindMin(root->rchild);elsetemp=FindMin(root->lchild);int nData = temp->data;Dest = FindNodeAndPos(root, nData, &Parent, &Pos);Delete_A_Node_With_One_Child(Parent, Dest, Pos);root->data = nData;}else{Parent = NULL, Dest = NULL;Pos = 0;Dest = FindNodeAndPos(root, key, &Parent, &Pos);if (Dest == NULL){printf("没有该结点,删除失败!\n");return;}// 当待删除结点没有左右子树时if (Dest->lchild == NULL && Dest->rchild == NULL)Delete_A_Node_With_One_Child(Parent, Dest, Pos);// 当待删除结点左右子树均存在时else if (Dest->lchild!=NULL && Dest->rchild!=NULL){Tree Cur = Dest, temp = FindMin(Dest->rchild);int nData = temp->data;Parent = NULL, Dest = NULL;Pos = 0;Dest = FindNodeAndPos(root, nData, &Parent, &Pos);Delete_A_Node_With_One_Child(Parent, Dest, Pos);Cur->data = nData;}// 当待删除结点只有一个子树时elseDelete_A_Node_With_One_Child(Parent, Dest, Pos);}}// 清空整个树Tree MakeEmpty(Tree root){if (root != NULL){MakeEmpty(root->lchild);MakeEmpty(root->rchild);free(root);}return NULL;}// 前序遍历void PreOrder(Tree root){if (root != NULL){printf("%d ", root->data);PreOrder(root->lchild);PreOrder(root->rchild);}}// 中序遍历void InOrder(Tree root){if (root != NULL){InOrder(root->lchild);printf("%d ", root->data);InOrder(root->rchild);}}// 后序遍历void PostOrder(Tree root){if (root != NULL){PostOrder(root->lchild);PostOrder(root->rchild);printf("%d ", root->data);}}// 以三种遍历方式打印出所有结点void Print(Tree root){printf("前序遍历: ");PreOrder(root);printf("\n");printf("中序遍历: ");InOrder(root);printf("\n");printf("后序遍历: ");PostOrder(root);printf("\n");}int main(){Tree root = NULL;for (int i = 0; i < 10; i++){root = Insert(root, rand() % 100);}root = Insert(root, 45);Print(root);printf("\n删除一个结点后\n\n");Delete_Node_With_Pos(root, 58);Print(root);printf("\n");root = MakeEmpty(root);system("pause");return 0;}
0 0
- 数据结构之二叉查找树的建立遍历删除
- 顺序二叉树的建立、查找、删除、插入、替换、遍历
- 二叉树的建立,删除,查找,插入,输出(数据结构)
- 二叉查找树的建立,遍历,查找
- 数据结构之二叉树(遍历、建立、深度)
- 数据结构之二叉树(遍历、建立、深度)
- 数据结构之二叉树(遍历、建立、深度)
- 数据结构之二叉树(遍历、建立、深度)
- 数据结构之二叉树(遍历、建立、深度)
- 数据结构之二叉树(遍历、建立、深度)
- 数据结构实验之二叉树的建立与遍历
- 数据结构之二叉树的建立与遍历
- 数据结构实验之二叉树的建立与遍历
- 数据结构实验之二叉树的建立与遍历
- 数据结构实验之二叉树的建立与遍历
- 数据结构实验之二叉树的建立与遍历
- 2136 数据结构实验之二叉树的建立与遍历
- 2136 数据结构实验之二叉树的建立与遍历
- Leetcode Longest Common Prefix
- 黑马程序员——Objective-C程序设计(第4版)学习笔记之17-内存管理和自动引用计数——黑马 IOS 技术博客
- 关于iOS 8.0模拟器不能使用中文输入法
- C#客户端和服务端数据的同步传输
- 黑马程序员——Objective-C程序设计(第4版)学习笔记之18-复制对象——黑马 IOS 技术博客
- 数据结构之二叉查找树的建立遍历删除
- 初识C#——流程控制
- 黑马程序员——Objective-C程序设计(第4版)学习笔记之19-归档——黑马 IOS 技术博客
- 20141221
- SQL Server中事务日志已满的原因以及解决办法
- leetcode:Single Number 菜鸟解法
- 判断是否是手机号码
- 黑马程序员——Objective-C程序设计(第4版)学习笔记之20-Cocoa和Cocoa Touch简介——黑马 IOS 技术博客
- Android程序开发重新开始一