大话数据结构之二叉树

2024-08-29 15:52

本文主要是介绍大话数据结构之二叉树,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

一、概述

二叉树是一种非常重要的数据结构,它由节点组成,每个节点都包含三个部分:一个存储数据的元素(如整数、浮点数、字符、字符串等),一个指向左子节点的指针,以及一个指向右子节点的指针。二叉树的特点是每个节点最多有两个子节点,通常称为左子节点和右子节点。

二、常见类型

  1. 普通二叉树:没有额外约束的二叉树。
  2. 二叉搜索树(BST):二叉搜索树(也称为二叉排序树、有序二叉树)是一种特殊的二叉树,它满足这样的性质:左子树的所有节点的值都小于根节点的值;右子树的所有节点的值都大于根节点的值;适用于快速查找、插入和删除操作。
  3. 满二叉树:一个二叉树,如果每一个层的节点数都达到最大值,则这个二叉树就是满二叉树。也就是说,除了叶子节点外,每个节点都有两个子节点。
  4. 完全二叉树(Complete Binary Tree):每一层都被完全填充,除了最后一层,且最后一层的节点集中在左侧。
  5. 平衡二叉树
  •    AVL 树:任意节点的两个子树的高度差至多为 1。
  •    红黑树:通过颜色标记节点,并保持特定的平衡规则,以保证操作在对数时间内完成。

三、基本操作

1、遍历:前序遍历、中序遍历、后序遍历和层次遍历。

  • 前序遍历(Pre-order):访问根节点,遍历左子树,遍历右子树,图1的遍历顺序为:ABDHKECFIGJ
  • 中序遍历(In-order):遍历左子树,访问根节点,遍历右子树,图1的遍历顺序为:HKDBEAIFCGJ
  • 后序遍历(Post-order):遍历左子树,遍历右子树,访问根节点,图1的遍历顺序为:KHDEBIFJGCA
  • 层序遍历(Level-order):逐层访问节点,通常使用队列实现,图1的遍历顺序为:ABCDEFGHIJK
图1

2、插入:在二叉搜索树中,插入新的节点以保持树的排序属性。

3、删除:从二叉搜索树中删除节点,并重新组织树以维持其排序属性。

4、查找:在二叉树中查找具有特定值的节点。

#include <stdlib.h>
#include <stdio.h>typedef int TElemType;/* 二叉树的二叉链表结点结构定义 */
/* 结点结构 */
typedef struct Node_t
{/* 结点数据 */TElemType data;/* 左右孩子指针 */struct Node_t*lchild, *rchild;
} Node;/* 二叉树的前序遍历递归算法 */
void PreOrderTraverse(Node *T)
{if (T == NULL)return;/* 显示结点数据,可以更改为其他对结点操作 */printf("%d ", T->data);/* 再先序遍历左子树 */PreOrderTraverse(T->lchild);/* 最后先序遍历右子树 */PreOrderTraverse(T->rchild);
}/* 二叉树的中序遍历递归算法 */
void InOrderTraverse(Node *T)
{if (T == NULL)return;/* 中序遍历左子树 */InOrderTraverse(T->lchild);/* 显示结点数据,可以更改为其他对结点操作 */printf("%d ", T->data);/* 最后中序遍历右子树 */InOrderTraverse(T->rchild);
}/* 二叉树的后序遍历递归算法 */
void PostOrderTraverse(Node *T)
{if (T == NULL)return;/* 先后序遍历左子树 */PostOrderTraverse(T->lchild);/* 再后序遍历右子树 */PostOrderTraverse(T->rchild);/* 显示结点数据,可以更改为其他对结点操作 */printf("%d ", T->data);
}// 查找节点  
Node* search(Node* root, int key) 
{  if (root == NULL || root->data == key) {  return root;  }  if (key < root->data) {  return search(root->lchild, key);  } else {  return search(root->rchild, key);  }  
}// 查找最小节点(用于删除有两个子节点的节点时替换)  
Node* minValueNode(Node* node) 
{  Node* current = node;  while (current->lchild != NULL) {  current = current->lchild;  }  return current;  
}  // 删除节点  
Node* deleteNode(Node* root, int key) 
{  if (root == NULL) return root;  if (key < root->data) {  root->lchild = deleteNode(root->lchild, key);  } else if (key > root->data) {  root->rchild = deleteNode(root->rchild, key);  } else {  // 节点有两个子节点  if (root->lchild != NULL && root->rchild != NULL) {  Node* temp = minValueNode(root->rchild);  root->data = temp->data;  root->rchild = deleteNode(root->rchild, temp->data);  }  // 节点有一个子节点或没有子节点  else {  Node* temp = root->lchild ? root->lchild : root->rchild;  free(root);  return temp;  }  }  return root;  
}/* 插入节点到二叉搜索树 */
Node *insert(Node *node, TElemType value)
{if(node == NULL){	node = (Node *)malloc(sizeof(Node));node->data = value;node->lchild = NULL;node->rchild = NULL;return node;}if(value < node->data)node->lchild = insert(node->lchild, value);elsenode->rchild = insert(node->rchild, value);return node;
}int main(int argc, char *argv[])
{Node *root = NULL;root = insert(root, 50);insert(root, 30);insert(root, 20);insert(root, 40);insert(root, 70);insert(root, 60);insert(root, 80);//前序遍历printf("front:");PreOrderTraverse(root);printf("\n");//中序遍历printf("mid:");InOrderTraverse(root);printf("\n");//后序遍历printf("back:");PostOrderTraverse(root);printf("\n");//查找const Node *node = search(root, 80);if(node != NULL){printf("search:%d\n", node->data);} //删除deleteNode(root, 20);deleteNode(root, 70);//中序遍历printf("mid:");InOrderTraverse(root);printf("\n");return 0;
}

qq群交流:698593923

觉得有帮助的话,打赏一下呗。。

           

这篇关于大话数据结构之二叉树的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/1118293

相关文章

【数据结构】——原来排序算法搞懂这些就行,轻松拿捏

前言:快速排序的实现最重要的是找基准值,下面让我们来了解如何实现找基准值 基准值的注释:在快排的过程中,每一次我们要取一个元素作为枢纽值,以这个数字来将序列划分为两部分。 在此我们采用三数取中法,也就是取左端、中间、右端三个数,然后进行排序,将中间数作为枢纽值。 快速排序实现主框架: //快速排序 void QuickSort(int* arr, int left, int rig

6.1.数据结构-c/c++堆详解下篇(堆排序,TopK问题)

上篇:6.1.数据结构-c/c++模拟实现堆上篇(向下,上调整算法,建堆,增删数据)-CSDN博客 本章重点 1.使用堆来完成堆排序 2.使用堆解决TopK问题 目录 一.堆排序 1.1 思路 1.2 代码 1.3 简单测试 二.TopK问题 2.1 思路(求最小): 2.2 C语言代码(手写堆) 2.3 C++代码(使用优先级队列 priority_queue)

《数据结构(C语言版)第二版》第八章-排序(8.3-交换排序、8.4-选择排序)

8.3 交换排序 8.3.1 冒泡排序 【算法特点】 (1) 稳定排序。 (2) 可用于链式存储结构。 (3) 移动记录次数较多,算法平均时间性能比直接插入排序差。当初始记录无序,n较大时, 此算法不宜采用。 #include <stdio.h>#include <stdlib.h>#define MAXSIZE 26typedef int KeyType;typedef char In

leetcode105 从前序与中序遍历序列构造二叉树

根据一棵树的前序遍历与中序遍历构造二叉树。 注意: 你可以假设树中没有重复的元素。 例如,给出 前序遍历 preorder = [3,9,20,15,7]中序遍历 inorder = [9,3,15,20,7] 返回如下的二叉树: 3/ \9 20/ \15 7   class Solution {public TreeNode buildTree(int[] pr

【408数据结构】散列 (哈希)知识点集合复习考点题目

苏泽  “弃工从研”的路上很孤独,于是我记下了些许笔记相伴,希望能够帮助到大家    知识点 1. 散列查找 散列查找是一种高效的查找方法,它通过散列函数将关键字映射到数组的一个位置,从而实现快速查找。这种方法的时间复杂度平均为(

PHP实现二叉树遍历(非递归方式,栈模拟实现)

二叉树定义是这样的:一棵非空的二叉树由根结点及左、右子树这三个基本部分组成,根据节点的访问位置不同有三种遍历方式: ① NLR:前序遍历(PreorderTraversal亦称(先序遍历)) ——访问结点的操作发生在遍历其左右子树之前。 ② LNR:中序遍历(InorderTraversal) ——访问结点的操作发生在遍历其左右子树之中(间)。 ③ LRN:后序遍历(PostorderT

浙大数据结构:树的定义与操作

四种遍历 #include<iostream>#include<queue>using namespace std;typedef struct treenode *BinTree;typedef BinTree position;typedef int ElementType;struct treenode{ElementType data;BinTree left;BinTre

Python 内置的一些数据结构

文章目录 1. 列表 (List)2. 元组 (Tuple)3. 字典 (Dictionary)4. 集合 (Set)5. 字符串 (String) Python 提供了几种内置的数据结构来存储和操作数据,每种都有其独特的特点和用途。下面是一些常用的数据结构及其简要说明: 1. 列表 (List) 列表是一种可变的有序集合,可以存放任意类型的数据。列表中的元素可以通过索

浙大数据结构:04-树7 二叉搜索树的操作集

这道题答案都在PPT上,所以先学会再写的话并不难。 1、BinTree Insert( BinTree BST, ElementType X ) 递归实现,小就进左子树,大就进右子树。 为空就新建结点插入。 BinTree Insert( BinTree BST, ElementType X ){if(!BST){BST=(BinTree)malloc(sizeof(struct TNo

【数据结构入门】排序算法之交换排序与归并排序

前言         在前一篇博客,我们学习了排序算法中的插入排序和选择排序,接下来我们将继续探索交换排序与归并排序,这两个排序都是重头戏,让我们接着往下看。  一、交换排序 1.1 冒泡排序 冒泡排序是一种简单的排序算法。 1.1.1 基本思想 它的基本思想是通过相邻元素的比较和交换,让较大的元素逐渐向右移动,从而将最大的元素移动到最右边。 动画演示: 1.1.2 具体步