减治法实现插入排序,减治法实现二叉查找树(二叉搜索数,二叉排序数)的创建、插入与查找(含解析与代码实现)

 🎊【数据结构与算法】专题正在持续更新中,各种数据结构的创建原理与运用✨,经典算法的解析✨都在这儿,欢迎大家前往订阅本专题,获取更多详细信息哦🎏🎏🎏

🪔本系列专栏 -  数据结构与算法_勾栏听曲_0

🍻欢迎大家  🏹  点赞👍  评论📨  收藏⭐️

📌个人主页 - 勾栏听曲_0的博客📝

🔑希望本文能对你有所帮助,如有不足请指正,共同进步吧🏆

🎇非淡泊无以明志,非宁静无以致远。📈

减治法

⚫ 减治技术:利用一个问题给定实例的解与同样问题较小实例的解之间的某种关系,可将原问题从顶至下,或从底至上地解决。从顶至下导致递归算法,从底至上导致增量法(注:从求解问题的一个较小实例开始,迭代实现,往往要好于递归)。

⚫减治法的三种变化形式:减去一个常量、减去一个常量因子、减去的规模可变。

        减常量:每次迭代总是从实例中减去一个相同的常量(一般来说,这个常量为1)。
                例如,计算a"的值,f(n)=a"

                 乘法为基本操作,上述减常量算法时间效率为O(n)。
                

        减常因子:每次迭代总是从实例的规模中减去一个相同的常数因子(一般来说,这个常数因子为2)。

                和上述同样的例子,计算a"的值,f(n)=a"
                乘法为基本操作,上述减常因子算法效率为O(log n)。

        减可变规模: 算法在每次迭代时,规模减小的模式可变。例如,欧几里得算法:

gcd(m,n) = gcd(n,m mod n)

插入排序

        减治法最典型的案例之一便是插入排序。

        插入排序思想:假设较小数组A[O..n-2]已排序好,为了得到一个大小为n的有序数组,在A[0..n-2]中找到一个合适位置,将A[n-1]插入该位置。迭代实现的插入排序伪代码如下:

InsertionSort(A[O..n-1])
//用插入排序对给定数组排序
//输入:n个可排序元素构成的一个数组A[0..n一1]

//输出:非降序排列的数组A[0..n一1]
for i <- 1 to n-1 do

        v <- A[i]
        j <- i-1
        while j ≥ 0 and A[j] > v  do

                A[j + 1] <- A[j]
                j <- j-1
                A[j + 1] <- v

        例子:对数组89,45,68,90,29,34,17排序:

        视频演示:

插入排序

        代码实现:

#include<stdio.h>
#include<stdlib.h>

void insort(int *a,int n)
{
	printf("排序前为:");
	for(int i = 0; i < n;i++)
		printf("%d ",*(a + i));
	}
	for(int i = 1; i < n;i++)
	{
		for(int j = i-1;j >= 0;j--)
		{
			if(*(a+j+1) < *(a+j))		//如果前面的数比后面大,就交换
			{
				int t = *(a+j+1);
				*(a+j+1) = *(a+j); 
				*(a+j) = t;
			}
		}
		printf("\n排序中:");			//显示每循环一次之后的排序结果
		for(int i = 0; i < n;i++)
		{
			printf("%d ",*(a + i));
		}
	}
	printf("\n排序后为:");
	for(int i = 0; i < n;i++)
	{
		printf("%d ",*(a + i));
	}
	printf("\n");
}


int main(int argc,char * argv[])
{
	int *str = NULL;	//存储要排序的数组
	int n;				//存储排序数组个数
	printf("请输入要排序的个数:");
	scanf("%d",&n);
	str = (int *)malloc(n * sizeof(int));	//获取个数后,给str分配空间
	printf("请输入要排序的数据(以空格隔开):");
	for(int i = 0; i < n;i++)				//循环将数据写入str中
	{
		scanf("%d",(str + i));
	}

	insort( str , n);		//调用排序算法
}

二叉查找数

        二叉树的节点包含排序项集合的元素,每个节点一个元素,对于每个节点,其所有左子树的元素都小于这个节点,其所有右子树的元素都大于这个节点。
        二叉查找树查找一个键值v的过程:将v与树的根节点进行比较,若相等,直接返回,若小于,在左子树中继续查找,若大于,在右子树中继续查找。
        算法的每次迭代,都简化为在一棵更小的二叉查找子树中查找(注:由于子树的高度是不一样的,因此,每次减少的规模可能是不一样的)。

        在二叉查找树中查找与插入键具有相等的时间效率。最坏时间效率为0(n)(例如:当连续插入的键是一个递增或递减序列时),平均时间效率为0(log n)。

        创建

        算法思路:

二叉排序树的创建过程,实际上就是把一个结点加入到一颗二叉排序数中,并且保证其二叉排序性过程。
        不断重复二叉排序树的插入操作。
        二叉排序树的插入操作:
                1.找插入位置
                2.执行插入操作

/* 
create_sotr_tree:创建一颗二叉排序树
	返回值:
		二叉排序树的根节点指针
 */
BiTNode *create_sort_tree()
{
    //保存根结点的指针
    BiTNode *r = NULL;
    //step1 从键盘上获取数据
    int i = 0;
    char str[64] = {0};
    //gets(str);
	/*for(int i = 0;i<64;i++)
	{
		scanf("%s",&str[i]);
		if(str[i] == '0')
			break;
	}*/
	scanf("%s",str);
    while(str[i])
    {
        //step2 创建新的数据结点 并且把数据写进去
        BiTNode *pnew = malloc(sizeof(*pnew));
        pnew->data = str[i];
        pnew->lchild = NULL;
        pnew->rchild = NULL;
        r = inset_node(r,pnew);
        i++;
    }
    return r;
}

        插入与删除节点

        插入与删除都有多种情况需要考虑

插入

        二叉数是空数

        遍历找到应该挂的位置,子树为空时挂上去

删除

        删除的是叶子节点,直接删除

        删除的节点有右子树

        删除的节点有左子树

        删除的节点有左右子树

//在一棵二叉排序树中增加结点
BiTNode *inset_node(BiTNode *r, BiTNode *pnew)
{
    BiTNode *p = r;//遍历指针 用来查找挂结点的位置
    if(r == NULL)//从无到有  这棵树是一颗空树 那么新插入的结点就是数本身
    {
        return pnew;
    }
    if(pnew == NULL)
    {
        return r;
    }
    while(1)
    {
        if(pnew->data < p->data)
        {
            if(p->lchild == NULL)//如果p左孩子为空 直接挂上去
            {
                p->lchild = pnew;
                break;
            }
            p = p->lchild;
        }
        else if(pnew->data > p->data)
        {
            if(p->rchild == NULL)//如果p右孩子为空 直接挂上去
            {
                p->rchild = pnew;
                break;
            }
            p = p->rchild;
        }
        else
        {
            printf("data repeated\n");
            break;
        }

    }
    return r;
}


BiTNode *delete_node(BiTNode *r,u4 x)
{
	//step1 找到要删除的节点px,以及他的父节点pf
	BiTNode *px = r;
	BiTNode *pf = NULL;
	while(px)
	{
		if(px->data == x+48)
		{
			break;
		}
		else if(px->data > x)
		{
			pf = px;	//确保pf指向px 的父节点
			px = px->lchild;
		}
		else 	//px->data < x
		{
			pf = px;
			px = px->rchild;
		}
	}
	if(px == NULL)
	{
		return r;
	}

	//分情况删除
	if(px == r && px->lchild == NULL && px->rchild == NULL)	//根节点且左右节点都为空
	{
		free(r);
		printf("删除节点后,树为空!\n");
		return NULL;
	}
	else if(px == r && px->lchild == NULL)	//根节点且左节点为空
	{
		r = r->rchild;
		free(px);
	}
	else if(px == r && px->rchild == NULL)	//根节点且右节点为空
	{
		r = r->lchild;
		free(px);
	}
	else if(px->lchild == NULL && px->rchild == NULL)	//为叶子节点
	{
		if(pf->lchild == px)
		{
			pf->lchild = NULL;
			free(px);
		}
		else
		{
			pf->rchild = NULL;
			free(px);
		}
	}
	else if(px->lchild != NULL && px->rchild == NULL)	//只有右孩子
	{
		if(pf->lchild == px)
		{
			pf->lchild = px->lchild;
			px->lchild = NULL;
			free(px);
		}
		else
		{
			pf->rchild = px->lchild;
			px->lchild = NULL;
			free(px);
		}
	}
	else if(px->lchild == NULL && px->rchild != NULL)	//只有左孩子
	{
		if(pf->lchild == px)
		{
			pf->lchild = px->rchild;
			px->rchild = NULL;
			free(px);
		}
		else
		{
			pf->rchild = px->rchild;
			px->rchild = NULL;
			free(px);
		}
	}
	else	//px->lchild != NULL && px->rchild != NULL	//有两个度的节点
	{
		BiTNode *p = px;
		BiTNode *pre = NULL;
		p = p->rchild;
		while(p->lchild)
		{
			pre = p;
			p = p->lchild;
		}
		px->data = p->data;
		pre->lchild = NULL;
		free(p);
	}
	return r;
}

        查找

/*在一棵二叉排序树中查找节点值
	参数:
		@BiTNode *r:传入的二叉排序数
		@int n:要查找的数
	返回值:
		char *:返回这个值在树中的顺序(如“01101”,左0右1)
*/
char *Find_node(BiTNode *r, int n)
{
    BiTNode *p = r;			//遍历指针 用来查找结点的位置
    char *str = NULL;		//用来记录查找时的顺序
	str = (char *)malloc(sizeof(char)*128);
    if(r == NULL)			//这棵树是一颗空树,直接返回
    {
        return str;
    }
    for(int i = 0; ;i++)
    {
        if(n < p->data)		//n小于当前节点值,往左走,str中记0
        {
			sscanf("0",(str+i));
            if(p->lchild == NULL)//如果p左孩子为空 直接挂上去
            {
                printf("二叉排序树中没有这个树\n");
				str = NULL;
                break;
            }
            p = p->lchild;
        }
        else if(n > p->data)	//n小于当前节点值,往右走,str中记1
        {
			sscanf("1",(str+i));
            if(p->rchild == NULL)//如果p右孩子为空 直接挂上去
            {
                printf("二叉排序树中没有这个树\n");
				str = NULL;
                break;
            }
            p = p->rchild;
        }
        else
        {
            break;
        }
    }
    return str;
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mfbz.cn/a/991.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

嵌入式软件开发之Linux下C编程

目录 前沿 Hello World&#xff01; 编写代码 编译代码 GCC编译器 gcc 命令 编译错误警告 编译流程 Makefile 基础 何为 Makefile Makefile 的引入 前沿 在 Windows 下我们可以使用各种各样的 IDE 进行编程&#xff0c;比如强大的 Visual Studio。但是在Ubuntu 下如何进…

【Java版oj】day10 井字棋、密码强度等级

目录 一、井字棋 &#xff08;1&#xff09;原题再现 &#xff08;2&#xff09;问题分析 &#xff08;3&#xff09;完整代码 二、密码强度等级 &#xff08;1&#xff09;原题再现 &#xff08;2&#xff09;问题分析 &#xff08;3&#xff09;完整代码 一、井字棋 &a…

CAT8网线测试仪使用中:线缆的抗干扰参数解读以及线缆工艺改进注意事项

FLUKE Agent platform -深圳维信&#xff0c;带你更深入的了解铜缆测试&#xff0c;详细为您讲解什么是TCL/ELTCL&#xff0c;他们对数据的传输到底有什么影响呢&#xff1f; 前情分析&#xff1a;为什么用双绞线传输信号&#xff1f;&#xff08;一图就懂&#xff09; TCL&a…

【深度解刨C语言】符号篇(全)

文章目录一.注释二.续行符与转义符1.续行符2.转义符三.回车与换行四.逻辑操作符五.位操作符和移位操作符六.前置与后置七.字符与字符串八./和%1.四种取整方式2.取模与取余的区别和联系3./两边异号的情况1.左正右负2.左负右正九.运算符的优先级一.注释 注释的两种符号&#xff…

Sentinel

SentinelSentinel介绍什么是Sentinel?为什么需要流量控制&#xff1f;为什么需要熔断降级&#xff1f;一些普遍的使用场景本文介绍参考&#xff1a;Sentinel官网《Spring Cloud Alibaba 从入门到实战.pdf》Sentinel下载/安装项目演示构建项目控制台概览演示之前需先明确&#…

【webrtc】ICE 到VCMPacket的视频内存分配

ice的数据会在DataPacket 构造是进行内存分配和拷贝而后DataPacket 会传递给rtc模块处理rtc模块使用DataPacket 构造rtp包最终会给到OnReceivedPayloadData 进行rtp组帧。吊炸天的是DataPacket 竟然没有声明析构方法。RtpVideoStreamReceiver::OnReceivedPayloadData 的内存是外…

3.网络爬虫——Requests模块get请求与实战

Requests模块get请求与实战requests简介&#xff1a;检查数据请求数据保存数据前言&#xff1a; 前两章我们介绍了爬虫和HTML的组成&#xff0c;方便我们后续爬虫学习&#xff0c;今天就教大家怎么去爬取一个网站的源代码&#xff08;后面学习中就能从源码中找到我们想要的数据…

普通Java工程师 VS 优秀架构师

1 核心能力 1.1 要成为一名优秀的Java架构师 只懂技术还远远不够&#xff0c;懂技术/懂业务/懂管理的综合型人才&#xff0c;才是技术团队中的绝对核心。 不仅仅是架构师&#xff0c;所有的技术高端岗位&#xff0c;对人才的综合能力都有较高的标准。 架构路线的总设计师 规…

安卓渐变的背景框实现

安卓渐变的背景框实现1.背景实现方法1.利用PorterDuffXfermode进行图层的混合&#xff0c;这是最推荐的方法&#xff0c;也是最有效的。2.利用canvas裁剪实现&#xff0c;这个方法有个缺陷&#xff0c;就是圆角会出现毛边&#xff0c;也就是锯齿。3.利用layer绘制边框1.背景 万…

多线程案例——阻塞队列

目录 一、阻塞队列 1. 生产者消费者模型 &#xff08;1&#xff09;解耦合 &#xff08;2&#xff09;“削峰填谷” 2. 标准库中的阻塞队列 3. 自己实现一个阻塞队列&#xff08;代码&#xff09; 4. 自己实现生产者消费者模型&#xff08;代码&#xff09; 一、阻塞队列…

【Pytorch】 理解张量Tensor

本文参加新星计划人工智能(Pytorch)赛道&#xff1a;https://bbs.csdn.net/topics/613989052 这是目录张量Tensor是什么&#xff1f;张量的创建为什么要用张量Tensor呢&#xff1f;总结张量Tensor是什么&#xff1f; 在深度学习中&#xff0c;我们经常会遇到一个概念&#xff…

更改Hive元数据发生的生产事故

今天同事想在hive里用中文做为分区字段。如果用中文做分区字段的话&#xff0c;就需要更改Hive元 数据库。结果发生了生产事故。导致无法删除表和删除分区。记一下。 修改hive元数据库的编码方式为utf后可以支持中文&#xff0c;执行以下语句&#xff1a; alter table PARTITI…

Vue初入,了解Vue的发展与优缺点

作者简介&#xff1a;一名计算机萌新、前来进行学习VUE,让我们一起进步吧。 座右铭&#xff1a;低头赶路&#xff0c;敬事如仪 个人主页&#xff1a;我叫于豆豆吖的主页 前言 从本章开始进行Vue前端的学习&#xff0c;了解Vue的发展&#xff0c;以及背后的故事。 一.vue介…

ASEMI代理瑞萨TW9992AT-NA1-GE汽车芯片

编辑-Z TW9992AT-NA1-GE是一款低功耗NTSC/PAL模拟视频解码器&#xff0c;专为汽车应用而设计。它支持单端、差分和伪差分复合视频输入。集成了对电池短路和对地短路检测&#xff0c;先进的图像增强功能&#xff0c;如可编程的自动对比度调整&#xff08;ACA&#xff09;和MIPI…

【Linux】网络编程套接字(下)

&#x1f387;Linux&#xff1a; 博客主页&#xff1a;一起去看日落吗分享博主的在Linux中学习到的知识和遇到的问题博主的能力有限&#xff0c;出现错误希望大家不吝赐教分享给大家一句我很喜欢的话&#xff1a; 看似不起波澜的日复一日&#xff0c;一定会在某一天让你看见坚持…

ASEMI代理MIMXRT1064CVJ5B原装现货NXP车规级MIMXRT1064CVJ5B

编辑&#xff1a;ll ASEMI代理MIMXRT1064CVJ5B原装现货NXP车规级MIMXRT1064CVJ5B 型号&#xff1a;MIMXRT1064CVJ5B 品牌&#xff1a;NXP /恩智浦 封装&#xff1a;LFGBA-196 批号&#xff1a;2023 安装类型&#xff1a;表面贴装型 引脚数量&#xff1a;196 类型&#…

【Hadoop-yarn-01】大白话讲讲资源调度器YARN,原来这么好理解

YARN作为Hadoop集群的御用调度器&#xff0c;在整个集群的资源管理上立下了汗马功劳。今天我们用大白话聊聊YARN存在意义。 有了机器就有了资源&#xff0c;有了资源就有了调度。举2个很鲜活的场景&#xff1a; 在单台机器上&#xff0c;你开了3个程序&#xff0c;分别是A、B…

Redis知识点汇总

前言 梳理知识 说一下项目中的Redis的应用场景 首先知道Redis的5大value类型: string,list,hash, set ,zset 2.基本上是缓存 3.为的是服务无状态, 4.无锁化 Redis是单线程还是多线程 1.无论什么版本,工作线程就一个 2.6.x高版本出现IO多线程

三天吃透操作系统面试八股文

本文已经收录到Github仓库&#xff0c;该仓库包含计算机基础、Java基础、多线程、JVM、数据库、Redis、Spring、Mybatis、SpringMVC、SpringBoot、分布式、微服务、设计模式、架构、校招社招分享等核心知识点&#xff0c;欢迎star~ Github地址&#xff1a;https://github.com/…

基于python的超市历年数据可视化分析

人生苦短 我用python Python其他实用资料:点击此处跳转文末名片获取 数据可视化分析目录人生苦短 我用python一、数据描述1、数据概览二、数据预处理0、导入包和数据1、列名重命名2、提取数据中时间&#xff0c;方便后续分析绘图三、数据可视化1、美国各个地区销售额的分布&…