您的位置:首页 > 健康 > 养生 > 数据结构--第六天

数据结构--第六天

2024/10/6 2:24:19 来源:https://blog.csdn.net/xujiashuo1/article/details/140938954  浏览:    关键词:数据结构--第六天

--树

        -树的基本概念

树结构通常用来储存逻辑关系为“一对多”的数据,例如:

上图的这些元素具有的就是 "一对多" 的逻辑关系,例如元素A同时和B、C、D有关系,元素D同时和A、H、I、J有关系等。 观察这些元素之间的逻辑关系会发现,它们整体上像一棵倒着的树,这也是将存储这些元素的结构起名为“树”的原因

        tips:树型结构可以保证数据的插入、删除、修改的速度

        -树的定义

          1. 树是由节点构成

          2. 树中除根节点,每一个节点都只有一个父节点,但是可以有多个子节点

          3. 根节点没有父节点

        -树中的专业术语

          节点:树结构存储的各个元素称为节点,例如:父节点,子节点,叶子节点

          节点的度:一个节点拥有子树的个数,就称为该节点的度

          叶子节点:没有子节点的节点,称为叶子节点

          边:一个节点到另一个节点的距离

          树的深度:树中结点的层数,根节点默认为第一层

          有序树: 如果一棵树中各个节点左子树和右子树的位置不能交换,那么这棵树就称为有序树

          无序树: 如果一棵树中各个节点左子树和右子树的位置可以交换,那么这棵树就称为无序树

          空树: 指没有任何节点的树,连根节点都没有

        -树的分类

           一般树:任意节点的子节点的个数不受限制,则称为一般树

           二叉树任意一个节点的子节点个数最多是2个

           森林:由多个树共同组成一片森林

        -二叉树的特性

           1.二叉树和链表一样,也是动态数据结构

            其结构体格式:

                struct Node{

                    datatype_t data;

                    struct Node* left;

                    struct Node* right;

                }

           2.二叉树具有唯一的根节点

           3.二叉树具有天然的递归结构(每个节点的左、右子树也是二叉树)

          满二叉树

                1>叶子节点出现在二叉树的最底层,除叶子节点之外的其他节点都有俩个子节点

                2>一个层数为k的满二叉树的总节点数为:2^k-1

                3>第i层上节点数为:2^(i-1) 

                4>一个层数为k的满二叉树的叶子节点个数(也就是最后一层)为:2^(k-1)

           完全二叉树

                概念:按照树的结构从上到下,从左到右依次将元素排列成树的形状

                性质:

                  1>根节点没有父节点

                  2>除根节点之外的任意节点(i)的父节点的索引为:(i-1)/2

                  3>任意节点的左子节点的的索引为:2*i+1

                  4>任意节点的右子节点的的索引为:2*i+2

        -二叉树的遍历

           二叉树的遍历是指从根结点触发,按照某种次序访问二叉树中所有节点,使得每个节点被访问且仅被访问一次

           四种常用遍历思想为:

                前序遍历:根节点-->左子树-->右子树

                中序遍历:左子树-->根节点-->右子树

                后序遍历:左子树-->右子树-->根节点

                层次遍历:只需按层次遍历即可

        -树示例代码

           main.c
#include "tree.h"void menu(){printf("--------------------------------\n");printf("1.create tree\n");printf("2.preorder tree\n");printf("3.midorder tree\n");printf("4.suffixorder tree\n");printf("show complete binary tree array\n");printf("0.exit\n");printf("--------------------------------\n");
}int main(){int select;node_t* root=NULL;do{menu();printf("请选择:");scanf("%d",&select);switch(select){case 1:while(getchar()!='\n');create_tree2(&root);break;case 2:printf("-------------------pre traversal----------------------\n");pre_traversal(root);putchar('\n');break;case 3:printf("-------------------middle traversal----------------------\n");middle_traversal(root);putchar('\n');break;case 4:printf("-------------------suf traversal----------------------\n");suf_traversal(root);putchar('\n');break;case 5:printf("-------------------level traversal----------------------\n");level_traversal(root);putchar('\n');break;case 0:printf("退出成功!\n");free(root);root=NULL;exit(EXIT_FAILURE);}}while(1);return 0;
}
        tree.c
#include "tree.h"//创建树的方法
void create_tree2(node_t** p_root){//创建一个节点char c;scanf("%c",&c);if(c=='#'){return; }node_t* p_node=(node_t*)malloc(sizeof(node_t));if(NULL==p_node){printf("malloc failure\n");return;}p_node->data=c;create_tree2(&(p_node->left));create_tree2(&(p_node->right));*p_root=p_node;
}node_t* create_tree(){//创造节点printf("input character:");char c;scanf("%c",&c);if(c=='#'){return NULL;}node_t* p_node=(node_t*)malloc(sizeof(node_t));if(NULL==p_node){printf("malloc failure.\n");return NULL;}p_node->data=c;//创建左子树p_node->left=create_tree();//创建右子树p_node->right=create_tree();return p_node;
}
//前序遍历
void pre_traversal(node_t* root){//递归终止条件if(NULL==root){return;}//递归操作printf("%-3c",root->data);pre_traversal(root->left);pre_traversal(root->right);
}
void middle_traversal(node_t* root){                          //递归终止条件if(NULL==root){                                    return;                                    }//递归操作middle_traversal(root->left);printf("%-3c",root->data);middle_traversal(root->right);                        
}
void suf_traversal(node_t* root){//递归终止条件if(NULL==root){return;}//递归操作suf_traversal(root->left);suf_traversal(root->right);printf("%-3c",root->data);
}void level_traversal(node_t* root){if(NULL==root){return;}//创建队列linkednode_t* queue=NULL;linkedlist_init(&queue);//1.将头节点入队linkedlist_insert_tail(queue,root);while(!linkedlist_is_empty(queue)){//2.出队node_t* node=linkedlist_remove_head(queue);printf("%-3c",node->data);//3.分别判断左右子树是否为空if(node->left!=NULL){linkedlist_insert_tail(queue,node->left);}if(node->right!=NULL){linkedlist_insert_tail(queue,node->right);}}
}
        tree.h
#ifndef _HEAD_COMPLETE_BT_H__
#define _HEAD_COMPLETE_BT_H__#include <stdio.h>
#include <stdlib.h>
#include <stdint.h>
#include <stdbool.h>
#include <string.h>
#include <errno.h>
#include "linkedlist.h"extern void create_tree2(node_t**);
extern void pre_traversal(node_t*);
extern void middle_traversal(node_t*);
extern void suf_traversal(node_t*);
extern void level_traversal(node_t*);
extern node_t* create_tree();#endif
        linkedlist.c
#include "linkedlist.h"void linkedlist_init(linkednode_t** p_head){                                         linkednode_t* p_node = (linkednode_t*)malloc(sizeof(linkednode_t));        if(p_node==NULL){                                        printf("malloc failure:%s\n",strerror(errno));   return;                                    }                                                        memset(p_node,0,sizeof(linkednode_t));                                                              p_node->next = NULL; *p_head = p_node;	
}// 添加的方法
bool linkedlist_insert_tail(linkednode_t* p_head,node_t* data){//将data添加到链表的尾部// 1、封装成节点linkednode_t* p_node = (linkednode_t*)malloc(sizeof(linkednode_t));if(p_node==NULL){printf("malloc failure:%s\n",strerror(errno));return false;}memset(p_node,0,sizeof(linkednode_t));p_node->data = data;p_node->next = NULL;// 1、找到链表的尾部linkednode_t* tail = p_head;while(tail->next!=NULL){tail= tail->next;}// 2、进行挂接tail->next=p_node;return true;
}bool linkedlist_is_empty(linkednode_t* head){return head == NULL || head->next==NULL;
}node_t* linkedlist_remove_head(linkednode_t* head){if(linkedlist_is_empty(head)){return NULL;}else{linkednode_t* delnode = head->next;head->next = head->next->next;return delnode->data;	}
}
        输出结果

版权声明:

本网仅为发布的内容提供存储空间,不对发表、转载的内容提供任何形式的保证。凡本网注明“来源:XXX网络”的作品,均转载自其它媒体,著作权归作者所有,商业转载请联系作者获得授权,非商业转载请注明出处。

我们尊重并感谢每一位作者,均已注明文章来源和作者。如因作品内容、版权或其它问题,请及时与我们联系,联系邮箱:809451989@qq.com,投稿邮箱:809451989@qq.com