数据结构总目录

排序二叉树

1. 结构解析

排序二叉树的结构规则很简单,只遵循一个基本规则:
那就是在二叉树中,选择任意根结点,其左子树都比根节点小,右子树都比根节点大。

排序二叉树结构图

观察如下二叉树,即可发现排序二叉树左小右大的规律,如图:

排序二叉树的基本操作

对于排序二叉树的插入操作较为简单,只需按照左小右大的规则进行判断即可。
而对于排序二叉树的删除操作,因为删除结点后依然要保持排序二叉树的基本规则,所以需要分类讨论

一、当所删除的结点《p》存在空的子树,共有三种情况(在代码中可归为一类),如下图:
(1)当p结点的左右子树均为空时,直接删除结点p即可

(2)当 p 结点左子树不为空,而右子树为空时,只需要将 p 的左子树接到 p 结点的父结点 f 下即可

(3)同理,当 p 结点右子树不为空,而左子树为空时,只需要将 p 的右子树接到 p 结点的父结点 f 下即可

二、当所删除的结点《p》的左右子树都存在时,且有如下已知条件:
已知 s 结点为 p 结点的左子树中最大的结点,则结点s的右子树必定为空
(1)第一种删除方式:将p结点的右子树转接到s结点的右子树上。
注意:虽然这样保证了排序二叉树基本规则,但是增加了二叉树的深度(高度),不利于查找

(2)第二种方式:将p结点和结点s的数据进行交换

2. 源代码:

#include <stdio.h>
#include <stdlib.h>typedef int DataType;
typedef struct BiTNode
{DataType data;struct BiTNode *lchild, *rchild;
}LinkBiTree;void InitBiTree(LinkBiTree **T)
{(*T) = NULL;printf("二叉树已初始化!\n");
}// 排序二叉树的插入操作
void SortBiTreeInsert(LinkBiTree **T, DataType x)
{if ((*T) == NULL){// 如果当前二叉树结点为空, 则为分配新的结点空间(*T) = (LinkBiTree *)malloc(sizeof(LinkBiTree));(*T)->data = x;(*T)->lchild = (*T)->rchild = NULL;}else if (x < (*T)->data){SortBiTreeInsert(&(*T)->lchild, x);}else if(x > (*T)->data){SortBiTreeInsert(&(*T)->rchild, x);}else{printf("插入失败!存在相同数据!\n");}
}// 排序二叉树的删除操作
void SortBiTreeDelete(LinkBiTree *T, DataType key)
{// 首先查询 [需要删除的结点(p)] 和 [被删除结点的父结点(f)]LinkBiTree *p = T, *f = NULL;while (p){if (key == p->data){break;}f = p;p =  key < p->data ? p->lchild : p->rchild; }if (!p){printf("删除失败!未查询到该结点%d\n", key);return;}LinkBiTree *q = p;// *****************1. 结点p存在空子树******************if(!p->lchild || !p->rchild){ // 1.1 选择非空的子孩子p = p->lchild ? p->lchild : p->rchild;// 1.2 父结点接入p结点的子树if (f->lchild == q)     // 被删除的是左孩子{f->lchild = p;      // 接入右子树}else if (f->rchild == q)// 被删除的是右孩子{f->rchild = p;      // 接入右子树}// 1.3 销毁结点free(q);}// *****************2. 结点p的左右子树都不为空******************else{// 2.1 从p结点的左子树中查找最大结点,用于替换p结点f = p;LinkBiTree *s = p->lchild;while (s->rchild){f = s;          //s的父结点s = s->rchild;  }// 2.2 替换结点p的数据p->data = s->data;// 2.3 s父结点f  接入 s的左子树if (f != p){f->rchild = s->lchild;}else{f->lchild = s->lchild;}// 2.4 销毁结点free(s);}printf("已完成删除操作!\n");
}// 先序遍历二叉树
void PreOrderTraverse(LinkBiTree *T)
{if (T != NULL){printf("%d ", T->data);PreOrderTraverse(T->lchild);PreOrderTraverse(T->rchild);}
}// 中序遍历二叉树
void InOrderTraverse(LinkBiTree *T)
{if (T != NULL){InOrderTraverse(T->lchild);printf("%d ", T->data);InOrderTraverse(T->rchild);}
}// 后序遍历二叉树
void PostOrderTraverse(LinkBiTree *T)
{if (T != NULL){PostOrderTraverse(T->lchild);PostOrderTraverse(T->rchild);printf("%d ", T->data);}
}int main()
{   printf("**********************************\n");printf("0:退出\t\t1:插入结点\t2:删除结点\n");printf("3:先序遍历\t4:中序遍历\t5:后序遍历\n");printf("**********************************\n");int k;DataType x;LinkBiTree *T;InitBiTree(&T);while (1){printf("请输入操作序号:");scanf("%d", &k);if (!k){break;}switch (k){case 1://参考用例:40 18 8 30 20 50 100 60 55 90 70 95 120 -9999printf("请输入插入数据:");while (scanf("%d", &x) != -1){if (x == -9999){break;}SortBiTreeInsert(&T, x);}printf("插入完成!\n");break;case 2:printf("请输入删除数据:");scanf("%d", &x);SortBiTreeDelete(T, x);break;case 3:printf("先序遍历:"); PreOrderTraverse(T);printf("\n");break;case 4: printf("中序遍历:"); InOrderTraverse(T); printf("\n");break;case 5: printf("后序遍历:"); PostOrderTraverse(T);printf("\n");break;default:break;}printf("\n");}system("pause");return 0;
}

3. 测试结果

用例参考图

测试结果

数据结构_排序二叉树(C语言)相关推荐

  1. 数据结构_线索二叉树(C语言)

    数据结构总目录 线索二叉树 1. 结构解析 线索二叉树,是对链式二叉树中的空指针的再次利用,在一般的链式二叉树中,叶子结点都存在左右空指针,所以为了不浪费这些空指针,于是就有了线索二叉树. 线索二叉树 ...

  2. 希尔排序python 简书_数据结构_排序_直接插入+希尔排序

    数据结构_排序_直接插入排序+希尔排序 其实主要是为了讲述希尔排序,不过插入排序是希尔排序的基础,因此先来讲直接插入排序. 一.直接插入排序 1.原理 下标 0 1 2 3 4 5 6 7 8 -- ...

  3. (数据结构)排序二叉树

    (数据结构)排序二叉树 建立并中序遍历一个排序二叉树 排序二叉树是指左子树的所有节点的值均小于它根节点的值,右子树的所有节点的值均大于它根节点的值,如下图是一棵排序二叉树 输入: 输入有一行,表示若干 ...

  4. Java数据结构学习——排序二叉树

    目录 前言 正文 排序二叉树的特点 插入节点 删除树节点 删除的节点是叶子节点 删除的节点存在左或者右子节点 删除的节点存在左右两子节点 遍历节点 先序遍历 中序遍历 后续遍历 全部代码展示 总结 前 ...

  5. 【数据结构】——排序二叉树

    排序二叉树即在构建二叉树的时候就对二叉树进行排序了,当中序遍历二叉树的时候即可得到一个有序的数列: 排序二叉树的规则就是: 若他的左子树不空,则左子树上所有结点的值均小于它的根结构的值: 若他的右子树 ...

  6. 数据结构之——排序二叉树、平衡二叉树和线索二叉树

    1.排序二叉树 排序二叉树(BST)也称二叉查找树,排序二叉树或者是一棵空树,或者是一棵具有下列特性的非空二叉树: (1)若左子树非空,则左子树上所有结点关键字值小于根节点的关键字值. (2)若右子树 ...

  7. 数据结构之排序算法(C语言)

    一.冒泡排序 冒泡排序是最简单的排序之一了,其大体思想就是通过与相邻元素的比较和交换来把小的数交换到最前面.这个过程类似于水泡向上升一样,因此而得名.举个栗子,对5,3,8,6,4这个无序序列进行冒泡 ...

  8. 数据结构_排序算法总结

    作者丨fredal https://www.jianshu.com/p/28d0f65aa6a1 所有内部排序算法的一个总结表格 简单选择排序 首先在未排序序列中找到最小(大)元素,存放到排序序列的起 ...

  9. 二叉树的递归遍历算法c语言 数据结构,递归创建二叉树c语言实现+详细解释

    该楼层疑似违规已被系统折叠 隐藏此楼查看此楼 void CreatBiTree(BiTree T) { char a; scanf("%c",&a); if(a=='@') ...

最新文章

  1. 用于区分IE的:条件注释
  2. try catch finally
  3. Java并发编程实战——volatile
  4. dspq值多少最好_蜂蜜纯度42的意思?蜂蜜纯度多少度好?
  5. oracle如何储存超长汉子_厦门到惠州整车运输超长超宽超重运输
  6. iOS开发UI篇--仿射变换(CGAffineTransform)使用小结
  7. [JZOJ6347] 【NOIP2019模拟2019.9.8】ZYB玩字符串
  8. 物流管理,快递单号查询查快递到哪了
  9. Nessus 扫描web服务
  10. Fourier变换基础
  11. Eight-point algorithm
  12. 总结 : 论文--Financial Distress Prediction
  13. 南城故事---教你一招就能让安卓手机变得飞快!
  14. 复制文本功能兼容 微信ios 火狐浏览器
  15. 大型Android项目架构:基于组件化+模块化+Kotlin+协程+Flow+Retrofit+Jetpack+MVVM架构实现WanAndroid客户端
  16. 如何用iptables限制BT、电驴等网络流量
  17. 路印协议项目进度报告(第37期)
  18. 利用Excel数据爬虫
  19. 猿创征文|最长回文子串-力扣
  20. app定位、地图、坐标系的那些坑

热门文章

  1. Simulink自动代码生成:原子子系统(Atomic Subsystem)
  2. 在不连接打印机的情况下,为打印机安装驱动程序
  3. win10设置Mongodb启动为Windows服务自启动
  4. 《基于历史拥堵图和共识日识别的交通拥堵和出行时间预测》
  5. 【HTML学生作业网页】基于HTML+CSS+JavaScript仿南京师范大学泰州学院(11页)
  6. C语言输人两个正整数m和n,求其最大公约数和最小公倍数
  7. Dockerfile 中文参考文档
  8. 物联卡长时间不用会过期吗?关于物联卡激活和销户规则
  9. 计算机毕业设计java+ssm框架共享充电宝管理系统(源码+系统+mysql数据库+Lw文档)
  10. 入手评测 惠普暗影精灵 7怎么样