首页 > 编程语言 >排序算法之二叉树排序详细解读(附带Java代码解读)

排序算法之二叉树排序详细解读(附带Java代码解读)

时间:2024-09-02 09:50:50浏览次数:7  
标签:遍历 二叉 解读 插入 二叉树 排序 root 节点

二叉树排序(Binary Tree Sort)是一种基于二叉搜索树(Binary Search Tree, BST)实现的排序算法。它的基本思想是利用二叉搜索树的性质来实现排序,通过将元素插入到二叉搜索树中,然后对树进行中序遍历来获取排序后的元素。

基本概念

  1. 二叉搜索树(BST):

    • 对于二叉搜索树中的每一个节点,其左子树中的所有节点值都小于当前节点的值,而右子树中的所有节点值都大于当前节点的值。
    • 这种结构使得在 BST 中查找、插入和删除操作具有 O(log n) 的平均时间复杂度(假设树是平衡的)。
  2. 排序过程:

    • 插入:将待排序的元素逐个插入到二叉搜索树中。
    • 中序遍历:对二叉搜索树进行中序遍历,这样遍历得到的节点值就是排序好的结果。

排序过程

  1. 构建二叉搜索树:

    • 从空树开始,将待排序的元素依次插入到二叉搜索树中。
    • 插入时,按照 BST 的规则将元素放置在正确的位置上。
  2. 中序遍历:

    • 对二叉搜索树进行中序遍历。中序遍历是按照左子树 → 根节点 → 右子树的顺序访问节点,这样可以得到一个升序排列的元素序列。

示例

假设待排序的数组为:[7, 3, 10, 1, 5, 8, 12]

步骤 1: 插入元素

构建二叉搜索树的过程如下:

  • 插入 7:树的根节点为 7。
  • 插入 3:3 小于 7,插入 7 的左子树。
  • 插入 10:10 大于 7,插入 7 的右子树。
  • 插入 1:1 小于 7,并且 1 小于 3,插入 3 的左子树。
  • 插入 5:5 小于 7,但 5 大于 3,插入 3 的右子树。
  • 插入 8:8 大于 7,但 8 小于 10,插入 10 的左子树。
  • 插入 12:12 大于 7,并且 12 大于 10,插入 10 的右子树。

          7
        /     \
      3       10
    /  \      /    \
  1    5   8    12

步骤 2: 中序遍历

对树进行中序遍历(左子树 → 根节点 → 右子树)得到排序结果:

  1. 遍历 1 → 3 → 5 → 7 → 8 → 10 → 12

排序后的结果为:[1, 3, 5, 7, 8, 10, 12]

算法复杂度

  • 时间复杂度:
    • 最坏情况: O(n^2),当树退化为链表(即所有节点只有左子树或右子树时)。
    • 平均情况: O(n log n),当树保持平衡时。
  • 空间复杂度:
    • 最坏情况: O(n),用于存储树的节点。
    • 平均情况: O(n),用于存储树的节点和递归栈空间。

优缺点

优点
  1. 排序稳定:树的构造过程和遍历保证了排序的稳定性。
  2. 适应性强:可以动态地插入和删除元素,适合需要频繁更新数据的场景。
缺点
  1. 空间复杂度:需要额外的空间来存储树结构。
  2. 最坏情况性能:在最坏情况下,二叉树可能退化为链表,导致时间复杂度达到 O(n^2)。为避免这种情况,可以使用自平衡的二叉搜索树(如 AVL 树或红黑树)来优化性能。

Java代码解读

public class BinaryTreeSort {

    // 二叉搜索树节点
    static class TreeNode {
        int value;
        TreeNode left, right;

        TreeNode(int value) {
            this.value = value;
            this.left = this.right = null;
        }
    }

    // 插入节点到二叉搜索树
    private static TreeNode insert(TreeNode root, int value) {
        if (root == null) {
            return new TreeNode(value);
        }
        if (value < root.value) {
            root.left = insert(root.left, value);
        } else {
            root.right = insert(root.right, value);
        }
        return root;
    }

    // 中序遍历二叉搜索树
    private static void inorderTraversal(TreeNode root, int[] arr, int[] index) {
        if (root != null) {
            inorderTraversal(root.left, arr, index);
            arr[index[0]++] = root.value;
            inorderTraversal(root.right, arr, index);
        }
    }

    // 主排序方法
    public static void binaryTreeSort(int[] arr) {
        if (arr.length == 0) return;

        // 1. 构建二叉搜索树
        TreeNode root = null;
        for (int value : arr) {
            root = insert(root, value);
        }

        // 2. 中序遍历树并存储结果
        int[] index = {0};
        inorderTraversal(root, arr, index);
    }

    public static void main(String[] args) {
        int[] arr = {7, 3, 10, 1, 5, 8, 12};
        System.out.println("排序前的数组:");
        for (int num : arr) {
            System.out.print(num + " ");
        }
        System.out.println();

        binaryTreeSort(arr);

        System.out.println("排序后的数组:");
        for (int num : arr) {
            System.out.print(num + " ");
        }
    }
}

代码说明

  1. TreeNode 类:

    • 表示二叉树的节点,包括值、左子节点和右子节点。
  2. insert 方法:

    • 将元素插入到二叉搜索树中,根据值确定插入位置。
  3. inorderTraversal 方法:

    • 对二叉搜索树进行中序遍历,并将遍历结果存储到数组中。
  4. binaryTreeSort 方法:

    • 构建二叉搜索树,然后通过中序遍历将排序结果存储到输入数组中。
  5. main 方法:

    • 测试二叉树排序算法,输出排序前后的数组。

标签:遍历,二叉,解读,插入,二叉树,排序,root,节点
From: https://blog.csdn.net/m0_61840987/article/details/141808713

相关文章

  • 二叉树的直径(LeetCode)
    题目给你一棵二叉树的根节点,返回该树的 直径 。二叉树的 直径 是指树中任意两个节点之间最长路径的 长度 。这条路径可能经过也可能不经过根节点 root 。两节点之间路径的 长度 由它们之间边数表示。解题classTreeNode:def__init__(self,val=0,left=......
  • 插入排序
    #include<stdio.h>#include<stdlib.h>#defineASIZE(a)(sizeof(a)/sizeof(a[0]))voidinsert_sort(int*a,intsize){for(inti=1;i<size;i++){intvalue=a[i];intj=i-1;for(;j>=0;j--)......
  • 代码随想录刷题day13丨二叉树理论基础,递归遍历,迭代遍历,统一迭代,层序遍历
    代码随想录刷题day13丨二叉树理论基础,递归遍历,迭代遍历,统一迭代,层序遍历1.二叉树理论基础1.1二叉树种类满二叉树概述:如果一棵二叉树只有度为0的结点和度为2的结点,并且度为0的结点在同一层上,则这棵二叉树为满二叉树。这棵二叉树为满二叉树,也可以说深度为k,有2^k-1个节......
  • JavaSE-递归法解决二分查找、快速排序
    704.二分查找https://leetcode.cn/problems/binary-search/packagedemo;publicclassBinarySearch{publicstaticvoidmain(String[]args){BinarySearchbr=newBinarySearch();System.out.println(br.search(newint[]{1,2,3,4,5,6,7......
  • 堆排序python实现
    一,树与二叉树1,树        树是一种数据结构,比如目录结构。        树是由n各节点组成的集合:    1.如果n=0,那存在一个节点作为数的根节点,其他节点可以分为m个集合,每个集合本身又是一颗树,比如:树的相关概念,比如根节点,叶子节点什么的不做过多介绍......
  • 六大排序(算法详解+模板+例题)
    一.排序算法是什么排序算法(SortingAlgorithms)是一种数据结构操作,它的目的是将一串元素按照特定的顺序规则组织起来。常见的排序算法有升序(从小到大)和降序(从大到小)排列,如冒泡排序、希尔排序、插入排序、选择排序、快速排序、归并排序等。排序的主要目的是为了方便查找、分析数......
  • 【数据结构】二叉树基础(带你了解二叉树)
     ......
  • 使用Golang的协程竟然变慢了|100万个协程的归并排序耗时分析
    前言这篇文章将用三个版本的归并排序,为大家分析使用协程排序的时间开销(被排序的切片长度由128到1000w)本期demo地址:https://github.com/BaiZe1998/go-learning往期视频讲解......
  • python动画教程|Animations using Matplotlib-官网教程程序解读
    随着python学习的深入,我们不可避免进入画图模块matplotlib,也不可避免会遇到制作动画的需求。【1】官网教程如何学习python制作动画,最简单的就是直奔官网:https://matplotlib.org/stable/users/explain/animations/animations.html#animations它给出很长的代码,下面是除引入nu......
  • 闪存刷新机制文献的解读
    闪存刷新机制文献的解读前言一、文献信息1、标题:FlashCorrect-and-Refresh:Retention-AwareErrorManagementforIncreasedFlashMemoryLifetime2、作者来源:卡耐基梅隆大学二、Motivation三、Technique(FlashCorrect-and-Refresh,FCR)1、Reprogrammingin-pl......