数据结构排序二叉树(下)

这篇具有很好参考价值的文章主要介绍了数据结构排序二叉树(下)。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

哎,调了几天深度学习模型,今天来更新排序二叉树

文章目录

前言

一、排序二叉树的结构定义

二、在排序二叉树添加数据

三、定义创建排序二叉树函数

四、查找一棵二叉排序树中的结点x的所在层数

五、删除二叉排序树中T关键字x的节点

六、查找二叉排序树中的所有小于key的关键字

七、已知二叉排序中每个节点值为整形,采用二叉链表存储,编写算法删除二叉排序树中所有关键字小于x的

八.总结与验证


前言

排序二叉树就这几个习题了,但实际上还有更难得几道习题,因为实现起来真的难,而且在使用中也难用到所以就给大家几道简单的例子,帮助大家来熟悉.


一、排序二叉树的结构定义

typedef int ElemType;
//二叉排序树左>根>右,树中没有重复值
//二叉排序树的数据结构
typedef struct BSTNode {
	ElemType data;//数据节点类型为int
	struct BSTNode* lchild;
	struct BSTNode* rchild;
}BSTNode,*BSTree;

其实就是二叉树的数据结构只是对树中节点数据有约束.

二、在排序二叉树添加数据

//插入节点函数
void insertNode(BSTree& T, ElemType e) {
	if (T == NULL) {//找到合适的位置插入节点
		BSTNode* pNode = (BSTNode*)malloc(sizeof(BSTNode));
		assert(pNode);
		pNode->data = e;
		pNode->lchild = NULL;
		pNode->rchild = NULL;
		T = pNode;//别忘了链接上
	}
	else if (T->data > e) {//插入左子树
		insertNode(T->lchild, e);
	}
	else if (T->data < e) {//插入右子树
		insertNode(T->rchild, e);
	}
}

由于二叉树左>根>右所以在构建二叉树使需要满足要求.

算法思想:运用递归思想,将待插入数据与当前节点比较如果小于当前节点数据表明插入数据应插在当前节点的左子树,反之当如果插入数据比当前的节点数据大,则表明插入数据应插到当前数据的右子树,直到遇到空节点表示找到插入位置,申请节点插入即可.

三、定义创建排序二叉树函数

//定义创建二叉排序树函数
BSTNode* creatBSTree() {
	BSTNode* T = NULL;
	ElemType enternum = 999999;//999999表示退出输入
	printf("请输入序列(以999999作为结束标志):");
	while (scanf("%d", &enternum) && enternum != 999999) {
		insertNode(T, enternum);
	}
	return T;
}

就依次插入节点就可以了.

四、查找一棵二叉排序树中的结点x的所在层数

//例1:查找一棵二叉排序树中的结点x的所在层数
int nodelevel(BSTree T, int level,ElemType x) {
	if (T == NULL) {//没找到返回0
		return 0;
	}
	else if (T->data > x) {//左子树寻找
		return nodelevel(T->lchild, level+1, x);
	}
	else if (T->data < x) {//右子树寻找
		return nodelevel(T->rchild, level+1, x);
	}
	else {
		return level;//返回层次
	}
}

算法思想:采用递归的形式,但传参时传入一个层数,找到返回即可,注意这里层数是值传递,不是址传递.

五、删除二叉排序树中T关键字x的节点

//例2:删除二叉排序树中T关键字x的节点
//算法思想:首先找到节点x此时就要分情况讨论(1)节点既没有左孩子又没有右孩子,直接删去节点并将指针制空;
//(2)节点只有左孩子(或只有右孩子),指针指向左孩子(右孩子)并删除节点;
//(3)节点既有左孩子又有右孩子,此时有两种处理方案1.找到左子树的最大节点将右孩子链接到最大节点的右指针
//2.找到右子树的最小节点,将左孩子链接到最小节点的左指针
void deleteOperation(BSTree& T) {
	if (T == NULL) return;
	if (T->lchild == NULL && T->rchild == NULL) {
		free(T);
		T = NULL;
	}
	else if (T->lchild != NULL && T->rchild == NULL) {
		BSTNode* tmp = T;
		T = T->lchild;
		free(tmp);
		tmp = NULL;
	}
	else if (T->lchild == NULL && T->rchild != NULL) {
		BSTNode* tmp = T;
		T = T->rchild;
		free(tmp);
		tmp = NULL;
	}
	else {//既有左孩子又有右孩子
		BSTNode* pMaxnode = T->lchild;
		while (pMaxnode->rchild != NULL) {
			pMaxnode = pMaxnode->rchild;
		}
		pMaxnode->rchild = T->rchild;
		BSTNode* tmp = T;
		T = T->lchild;
		free(tmp);
		tmp = NULL;
	}
}
//查找并删除节点
void deletenode(BSTree &T,ElemType x) {
	if (T != NULL) {
		if (T->data == x) {
			deleteOperation(T);
		}
		else if (T->data < x) {
			deletenode(T->rchild, x);
		}
		else {
			deletenode(T->lchild, x);
		}
	}

}

这个算法还有一个思想就是找到左子树最大的节点复制到删除节点上,递归在左子树删除左子树最大节点.

数据结构排序二叉树(下),数据结构与算法,数据结构,c语言,算法

字有点丑见谅.

六、查找二叉排序树中的所有小于key的关键字

//例3:查找二叉排序树中的所有小于key的关键字
void getSmallerkey(BSTree T, ElemType key) {
	if (T != NULL) {
		getSmallerkey(T->lchild, key);
		if (T->data < key) {
			printf("%d ", T->data);
			getSmallerkey(T->rchild, key);
		}
	}
}

七、已知二叉排序中每个节点值为整形,采用二叉链表存储,编写算法删除二叉排序树中所有关键字小于x的

//例4:已知二叉排序中每个节点值为整形,采用二叉链表存储,编写算法删除二叉排序树中所有关键字小于x的节点
//定义递归删除树函数
void deleteFunc(BSTree& T) {//递归删除树
	if (T != NULL) {
		deleteFunc(T->lchild);
		deleteFunc(T->rchild);
		free(T);
		T = NULL;
	}
}
//定义删除小于x节点的函数(采用先序遍历的思想)
void deleteSmallernode(BSTree &T,ElemType x) {
	if (T != NULL) {
		if (T->data == x) {//根节点等于x说明左子树都小于x递归删除
			deleteFunc(T->lchild);
		}
		else if (T->data < x) {//根节点小于x左子树均小于x,删除根节点在递归删除右子树小于x的节点
			deleteFunc(T->lchild);
			BSTNode* tmp = T;
			T = T->rchild;
			free(tmp);
			tmp = NULL;
			deleteSmallernode(T, x);
		}
		else {//根节点大于x递归删除左子树小于x的节点
			deleteSmallernode(T->lchild, x);
		}
	}
}

八.总结与验证

#define _CRT_SECURE_NO_WARNINGS 1
#include<stdio.h>
#include<malloc.h>
#include<assert.h>
typedef int ElemType;
//二叉排序树左>根>右,树中没有重复值
//二叉排序树的数据结构
typedef struct BSTNode {
	ElemType data;//数据节点类型为int
	struct BSTNode* lchild;
	struct BSTNode* rchild;
}BSTNode,*BSTree;
//插入节点函数
void insertNode(BSTree& T, ElemType e) {
	if (T == NULL) {//找到合适的位置插入节点
		BSTNode* pNode = (BSTNode*)malloc(sizeof(BSTNode));
		assert(pNode);
		pNode->data = e;
		pNode->lchild = NULL;
		pNode->rchild = NULL;
		T = pNode;//别忘了链接上
	}
	else if (T->data > e) {//插入左子树
		insertNode(T->lchild, e);
	}
	else if (T->data < e) {//插入右子树
		insertNode(T->rchild, e);
	}
}
//定义创建二叉排序树函数
BSTNode* creatBSTree() {
	BSTNode* T = NULL;
	ElemType enternum = 999999;//999999表示退出输入
	printf("请输入序列(以999999作为结束标志):");
	while (scanf("%d", &enternum) && enternum != 999999) {
		insertNode(T, enternum);
	}
	return T;
}
//中序遍历二叉排序树
void inorderTraverse(BSTree T) {
	if (T != NULL) {
		inorderTraverse(T->lchild);
		printf("%d ", T->data);
		inorderTraverse(T->rchild);
	}
}
//先序遍历二叉排序树
void preorderTraverse(BSTree T) {
	if (T != NULL) {
		printf("%d ", T->data);
		preorderTraverse(T->lchild);
		preorderTraverse(T->rchild);
	}
}
//遍历二叉排序树(先,中)
void Traverse(BSTree T) {//这函数主要是用来验证
	printf("中序遍历结果:");
	inorderTraverse(T);
	printf("\n");
	printf("先序遍历结果:");
	preorderTraverse(T);
	printf("\n");
}
//例1:查找一棵二叉排序树中的结点x的所在层数
int nodelevel(BSTree T, int level,ElemType x) {
	if (T == NULL) {//没找到返回0
		return 0;
	}
	else if (T->data > x) {//左子树寻找
		return nodelevel(T->lchild, level+1, x);
	}
	else if (T->data < x) {//右子树寻找
		return nodelevel(T->rchild, level+1, x);
	}
	else {
		return level;//返回层次
	}
}
//例2:删除二叉排序树中T关键字x的节点
//算法思想:首先找到节点x此时就要分情况讨论(1)节点既没有左孩子又没有右孩子,直接删去节点并将指针制空;
//(2)节点只有左孩子(或只有右孩子),指针指向左孩子(右孩子)并删除节点;
//(3)节点既有左孩子又有右孩子,此时有两种处理方案1.找到左子树的最大节点将右孩子链接到最大节点的右指针
//2.找到右子树的最小节点,将左孩子链接到最小节点的左指针
void deleteOperation(BSTree& T) {
	if (T == NULL) return;
	if (T->lchild == NULL && T->rchild == NULL) {
		free(T);
		T = NULL;
	}
	else if (T->lchild != NULL && T->rchild == NULL) {
		BSTNode* tmp = T;
		T = T->lchild;
		free(tmp);
		tmp = NULL;
	}
	else if (T->lchild == NULL && T->rchild != NULL) {
		BSTNode* tmp = T;
		T = T->rchild;
		free(tmp);
		tmp = NULL;
	}
	else {//既有左孩子又有右孩子
		BSTNode* pMaxnode = T->lchild;
		while (pMaxnode->rchild != NULL) {
			pMaxnode = pMaxnode->rchild;
		}
		pMaxnode->rchild = T->rchild;
		BSTNode* tmp = T;
		T = T->lchild;
		free(tmp);
		tmp = NULL;
	}
}
//查找并删除节点
void deletenode(BSTree &T,ElemType x) {
	if (T != NULL) {
		if (T->data == x) {
			deleteOperation(T);
		}
		else if (T->data < x) {
			deletenode(T->rchild, x);
		}
		else {
			deletenode(T->lchild, x);
		}
	}

}
//例3:查找二叉排序树中的所有小于key的关键字
void getSmallerkey(BSTree T, ElemType key) {
	if (T != NULL) {
		getSmallerkey(T->lchild, key);
		if (T->data < key) {
			printf("%d ", T->data);
			getSmallerkey(T->rchild, key);
		}
	}
}
//例4:已知二叉排序中每个节点值为整形,采用二叉链表存储,编写算法删除二叉排序树中所有关键字小于x的节点
//定义递归删除树函数
void deleteFunc(BSTree& T) {//递归删除树
	if (T != NULL) {
		deleteFunc(T->lchild);
		deleteFunc(T->rchild);
		free(T);
		T = NULL;
	}
}
//定义删除小于x节点的函数(采用先序遍历的思想)
void deleteSmallernode(BSTree &T,ElemType x) {
	if (T != NULL) {
		if (T->data == x) {//根节点等于x说明左子树都小于x递归删除
			deleteFunc(T->lchild);
		}
		else if (T->data < x) {//根节点小于x左子树均小于x,删除根节点在递归删除右子树小于x的节点
			deleteFunc(T->lchild);
			BSTNode* tmp = T;
			T = T->rchild;
			free(tmp);
			tmp = NULL;
			deleteSmallernode(T, x);
		}
		else {//根节点大于x递归删除左子树小于x的节点
			deleteSmallernode(T->lchild, x);
		}
	}
}
int main() {
	//创建一棵二叉排序树
	//8 5 4 7 9 10 999999
	BSTree T = creatBSTree();
	Traverse(T);
	printf("\n");
	int a = 10;
	printf("数据节点为%d的节点所在层次:%d\n", a,nodelevel(T, 1, a));
	printf("删除数据节点前树的结构\n");
	Traverse(T);
	deletenode(T, 5);
	printf("删除数据节点后树的结构\n");
	Traverse(T);
	printf("比8小的数据节点有:");
	getSmallerkey(T, 8);
	printf("\n");
	int b = 8;
	printf("删除比%d小的所有节点前\n",b);
	Traverse(T);
	deleteSmallernode(T, b);
	printf("删除比%d小的所有节点后\n", b);
	Traverse(T);
	return 0;
}

数据结构排序二叉树(下),数据结构与算法,数据结构,c语言,算法

兄弟们马上要到图啦,最有意思的一部分要到啦.加油哦文章来源地址https://www.toymoban.com/news/detail-808731.html

到了这里,关于数据结构排序二叉树(下)的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • 【数据结构】二叉排序树——平衡二叉树的调整

    参考视频: 懒猫老师-数据结构-(59)平衡二叉树【互动视频】 (1)什么是平衡二叉树 平衡二叉树(Balanced Binary Tree)是一种特殊的二叉查找树,它的目的是保持树的高度尽量平衡,以保证查找、插入、删除等操作的时间复杂度为 O(log n)。 常见的平衡二叉树算法包括 AVL 树、红

    2024年02月04日
    浏览(40)
  • 【数据结构】:二叉树与堆排序的实现

    树是一种非线性的数据结构,它是由n(n=0)个有限结点组成一个具有层次关系的集合把它叫做树是因为它看起来像一棵倒挂的树,也就是说它是根朝上,而叶朝下的有一个特殊的结点,称为根结点,根节点没有前驱结点 除根节点外,其余结点被分成M(M0)个互不相交的集合T1、

    2024年02月08日
    浏览(41)
  • 【数据结构】详解二叉树与堆与堆排序的关系

    🌇个人主页:平凡的小苏 📚学习格言:别人可以拷贝我的模式,但不能拷贝我不断往前的激情 🛸C语言专栏:https://blog.csdn.net/vhhhbb/category_12174730.html 🚀数据结构专栏:https://blog.csdn.net/vhhhbb/category_12211053.html         家人们更新不易,你们的👍点赞👍和⭐关注⭐真的对我

    2024年02月02日
    浏览(42)
  • 【数据结构和算法】--- 二叉树(3)--二叉树链式结构的实现(1)

    在学习二叉树的基本操作前,需先要创建一棵二叉树,然后才能学习其相关的基本操作。由于现在大家对二叉树结构掌握还不够深入,且为了方便后面的介绍,此处手动快速创建一棵简单的二叉树,快速进入二叉树操作学习,等二叉树结构了解的差不多时,我们反过头再来研

    2024年01月25日
    浏览(63)
  • 数据结构课设(五)二叉排序树与平衡二叉树的实现

    假定二叉排序树与平题所处理数据均为整型。分别采用二叉链表和顺序表作存储结构,实现对二叉衡二叉树的操作。具体要求如下: (1)用二叉链表作存储结构: ①读入一个整数序列L(要求该整数序列从磁盘文件读取),生成一棵二叉排序树②对二叉排序树T作中序遍历,输出结果

    2024年02月12日
    浏览(46)
  • 数据结构----完全二叉树的时间复杂度讲解,堆排序

    目录 一.建堆的时间复杂度 1.向上调整算法建堆 2.向下调整算法建堆 二.堆排序 1.概念 2.代码思路 3.代码实现 我们就以极端情况考虑时间复杂度(满二叉树+遍历所有层) 假设所有节点个数为N,树的高度为h N = 2^0+2^1+2^2......+2^(h-1) 即N = 2^h - 1 h = log(N+1) 时间复杂度我们以交换次数为

    2024年03月14日
    浏览(65)
  • 数据结构与算法-二叉树

            在计算机科学中,数据结构是组织和存储数据的基础框架,而算法则是处理这些数据的核心逻辑。在这众多的数据结构中,二叉树因其独特的层级结构、高效的搜索和插入操作,成为广泛应用的一种非线性数据结构。本文将深入探讨二叉树的定义、种类、操作方法

    2024年03月10日
    浏览(59)
  • 【数据结构与算法】—— 二叉树

    目录 一、树 1、初识树 2、树的一些概念 3、树的表示形式 二、二叉树 1、初识二叉树 2、两种特殊的二叉树 3、二叉树的性质  4、二叉树的遍历 5、实现一棵二叉树  6、二叉树题目(没代码的后面会给补上) (1)根节点没有前驱。 (2)子树的根节点只有一个前驱,可以有

    2024年04月09日
    浏览(48)
  • 数据结构---二叉树(C语言)

    空树 非空:根节点,根节点的左子树、根节点的右子树组成的。 从二叉树的定义来看,二叉树是递归定义的,因此我们可以用递归的形式来遍历二叉树。 1.1.1二叉树前中后序遍历(递归版) 访问根结点的顺序不同。 1.1.2 层序遍历 层序遍历是按照二叉树的高度,一层一层遍

    2024年02月06日
    浏览(48)
  • 【数据结构】二叉树-堆(top-k问题,堆排序,时间复杂度)

     🌈个人主页: 秦jh__https://blog.csdn.net/qinjh_?spm=1010.2135.3001.5343 🔥 系列专栏: 《数据结构》https://blog.csdn.net/qinjh_/category_12536791.html?spm=1001.2014.3001.5482 ​​ 目录 堆排序 第一种  ​编辑 第二种  TOP-K问题 建堆的时间复杂度 向下调整建堆的时间复杂度:  向上调整建堆的时间

    2024年01月21日
    浏览(61)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包