数据结构实验报告-实验五-构造二叉树和二叉树的层序遍历_哆啦一泓的博客-程序员宅基地

技术标签: 实验、考试与课设  

实验五 构造二叉树和二叉树的层序遍历

一、实验描述

1.  构造二叉树:给出一棵二叉树的先序(或后序)遍历结果,以及中序遍历结果,如何构造这棵树?假定遍历结果以数组方式输入,请写出相应函数,判断是否存在生成同样遍历结果的树,如果存在,构造这棵树。

2.  二叉树的层序遍历:使用队列作为辅助存储,按树的结点的深度,从根开始依次访问所有结点。

 

二、实验分析

(1)构造二叉树:

①根据前序遍历找到树的根节点,在中序遍历中找到根节点,将树分为左右两棵子树,找到前序遍历中两棵子树的位置,对两棵子树进行递归调用

(2)层序遍历:

①将根节点放入队列中

②从队列中取出节点,将左儿子和右儿子放入队列,输出当前节点的关键字

③重复步骤2,直到队列为空

 

三、实验设计

1.构造二叉树

#include<stdio.h>  
#include<stdlib.h>  
#include<time.h>  
#include<string.h>  
  
#define ARRAY_LENGTH(array) sizeof(array)/sizeof(*array)  
#define MY_RAND_MAX 100  
  
typedef struct NODE{  
    int val;  
    struct NODE *left;  
    struct NODE *right;  
}Node;  
  
static Node* newNode(int val,Node *left,Node *right){  
    Node *result = (Node*)malloc(sizeof(Node));  
    if(NULL != result){  
        result->val = val;  
        result->left = left;  
        result->right = right;  
    }  
    return result;  
}  
  
int cur = 1;  
  
Node* RecoverPreTree(int *pre,int *mid,int length){  
    if(0 == length)  
        return NULL;  
  
    int i = 0;  
    for(;mid[i]!=*pre;i++);  
    Node *root = newNode(*pre,NULL,NULL);  
    root->left = RecoverPreTree(pre+1,mid,i);  
    root->right = RecoverPreTree(pre+1+i,mid+1+i,length-1-i);  
    return root;  
}  
  
Node* Generate(int depth){  
    if(-1 == depth)  
        return NULL;  
    srand(rand());  
    return newNode(cur++,Generate(depth-1),Generate(depth-1));  
}  
  
int* PreTravesal(Node *root){  
    if(NULL == root){  
        int *result = (int*)malloc(sizeof(int));  
        *result = 0;  
        return result;  
    }  
  
    int *left = PreTravesal(root->left);  
    int *right = PreTravesal(root->right);  
    int *result = (int*)malloc(sizeof(int)*(*left+*right+2));  
    *result = 1+*left+*right;  
    *(result+1) = root->val;  
    memcpy(result+2,left+1,*left*sizeof(int));  
    memcpy(result+2+*left,right+1,*right*sizeof(int));  
    free(left);  
    free(right);  
    return result;  
}  
  
int* InTravesal(Node *root){  
    if(NULL == root){  
        int *result = (int*)malloc(sizeof(int));  
        *result = 0;  
        return result;  
    }  
  
    int *left = InTravesal(root->left);  
    int *right = InTravesal(root->right);  
  
    int *result = (int*)malloc(sizeof(int)*(*left+*right+2));  
    *result = 1+*left+*right;  
    memcpy(result+1,left+1,*left*sizeof(int));  
    *(result+*left+1) = root->val;  
    memcpy(result+2+*left,right+1,*right*sizeof(int));  
    free(left);  
    free(right);  
    return result;  
}  
  
void PrintPreTree(Node *root){  
    static int indent = 0;  
  
    if(NULL  == root)  
        return;  
  
    printf("\t");  
    printf("%d\n",root->val);  
  
    indent ++;  
    PrintPreTree(root->left);   
    PrintPreTree(root->right);  
    indent --;  
    return;  
}  
  
void PrintArray(int *array,int length){  
    for(int i = 0;i<length;i++)  
        printf("%d ",*(array++));  
}  
  
void DestroyTree(Node *root){  
    if(NULL == root)  
        return;  
      
    DestroyTree(root->left);  
    DestroyTree(root->right);  
    free(root);  
}  
  
int main(){  
  
    Node *tree = Generate(3);  
    PrintPreTree(tree);  
    printf("\n");  
    int *array1 = PreTravesal(tree);  
    PrintArray(array1+1,*array1);  
    printf("\n");  
    int *array2 = InTravesal(tree);  
    PrintArray(array2+1,*array2);  
  
    printf("\n");  
    Node *recover = RecoverPreTree(array1+1,array2+1,*array1);  
    PrintPreTree(recover);  
  
  
    free(array1);  
    free(array2);  
    DestroyTree(tree);  
    DestroyTree(recover);  
    return 0;  
}  

2.层序遍历

#include<stdio.h>  
#include<stdlib.h>  
#include<time.h>  
#include<string.h>  
  
#define ARRAY_LENGTH(array) sizeof(array)/sizeof(*array)  
#define MY_RAND_MAX 100  
  
typedef struct NODE{  
    int val;  
    struct NODE *left;  
    struct NODE *right;  
}Node;  
  
static Node* newNode(int val,Node *left,Node *right){  
    Node *result = (Node*)malloc(sizeof(Node));  
    if(NULL != result){  
        result->val = val;  
        result->left = left;  
        result->right = right;  
    }  
    return result;  
}  
  
typedef struct LIST{  
    Node *root;  
    struct LIST *next;  
}List;  
  
typedef struct QUEUE{  
    List *head;  
    List *tail;  
}Queue;  
  
Queue* newQueue(){  
    Queue *result = (Queue*)malloc(sizeof(Queue));   
    List *tmp = (List*)malloc(sizeof(List));  
    tmp->next = NULL;  
    result->head = tmp;  
    result->tail = result->head;   
    return result;  
}  
  
void Enqueue(Queue *queue,Node *root){  
    List *tmp = (List*)malloc(sizeof(List));  
    tmp->root = root;  
    tmp->next = NULL;  
    queue->tail->next = tmp;  
    queue->tail = queue->tail->next;  
}  
  
Node* Dequeue(Queue *queue){    
    if(NULL == queue->head->next)  
        return NULL;  

    List* tmp = queue->head->next;  
    Node* result = tmp->root;  
    queue->head->next = queue->head->next->next;  
    if(queue->head->next == NULL){  
        queue->tail = queue->head;  
    }  
    free(tmp);  
    return result;  
}  
  
int cur = 1;  
Node* Generate(int depth){  
    if(-1 == depth)  
        return NULL;  
  
    srand(rand());  
    return newNode(rand()%MY_RAND_MAX,Generate(depth-1),Generate(depth-1));  
}  
  
void PrintPreTree(Node *root){  
    static int indent = 0;  
   
    if(NULL  == root)  
        return;  
    for(int i = 0;i<indent;i++)  
        printf("\t");  
    printf("%d\n",root->val);  
  
    indent ++;  
    PrintPreTree(root->left);  
    PrintPreTree(root->right);  
    indent --;  
    return;  
}  
  
void DestroyTree(Node *root){  
    if(NULL == root)  
        return;  
      
    DestroyTree(root->left);  
    DestroyTree(root->right);  
    free(root);  
}  
  
void DestroyList(List *list){  
    while(NULL != list){  
        free(list);  
        list = list->next;  
    }  
}  
  
int main(){  
  
    Node *tree = Generate(3);  
    PrintPreTree(tree);  
    printf("\n");  
    Queue *queue = newQueue();  
    Enqueue(queue,tree);  
    while(queue->head!=queue->tail){  
        Node *tmp = Dequeue(queue);  
        if(NULL == tmp)  
            continue;  
        printf("%d ",tmp->val);  
        if(NULL != tmp->left)  
            Enqueue(queue,tmp->left);  
        if(NULL != tmp->right)  
            Enqueue(queue,tmp->right);  
    }  
  
    DestroyTree(tree);  
    DestroyList(queue->head);  
    free(queue);  
    return 0;  
}  

 

四、实验结论

1.构造二叉树:

如果使用线性扫描查找位置,则每次查找需要 O(N)的时间,如果二叉树平衡的话,则整个算法需要 O(NlgN)的时间。如果二叉树不平衡,则最坏情况需要 O(N^2)时间。为了提高效率,我们可以考虑使用哈希表来存储与查找根结点在中序遍历中的位置,每次查找只需要 O(1)的时间,这样构建整棵树只需要 O(N)的时间。

2.二叉树的层序遍历:

因为每个节点只访问一次,时间复杂度为 O(N)。

版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
本文链接:https://blog.csdn.net/lee1hong/article/details/103275329

智能推荐

webpack常用loader和plugin总结_用过那些常见的 loader plugin_MoLvSHan的博客-程序员宅基地

webpack常用loader和plugin总结loaderstyle-loader & css-loaderless-loaderpostcss-loaderfile-loader & url-loaderbabel-loader & @babel/preset-env & @babel/corebabel-polyfillpluginhtml-webpack-p..._用过那些常见的 loader plugin

C# button自定义控件_c#自定义控件按钮_rainlua的博客-程序员宅基地

最近在做一个项目关于C#按键的button是自定义的,先重写父类方法onpainted绘制button形状protected override void OnPaint(System.Windows.Forms.PaintEventArgs e) { base.OnPaint(e); System.Drawing.Drawing_c#自定义控件按钮

利用com.graphics.Camera 模拟ViewPager布局3D效果_Techck的博客-程序员宅基地

学习了很多自定义View的知识,终于有勇气自己写一个Demo的勇气了,还是要多实践啊!!!!!!!!!需要掌握的内容:坐标系等基础知识,View的绘制过程,画布的操作,Matrix原理,Matrix Camera原理,事件分发机制等。 这里我推荐一个网站,里面的内容很丰富也很有趣 http://www.gcssloop.com/customview/CustomViewIndex下面介

2021年个人工作总结_博客 2021年个人工作总结_ZePingPingZe的博客-程序员宅基地

2021年终个人工作总结尊敬的领导:您们好!旦夕之间2021已然逝去,怀揣着激动的心情对这一年的工作做一个总结,记录一下成长经验、不足和对新一年的规划。这一年,在领导及团队的共同努力下,本人完成了TA项目建设规划的所有工作任务,为项目组贡献了自己的一份绵薄之力。以下是这一年的个人工作总结:一、工作内容 2021年度,总共完成13个需求,6个技术方案的研究及参与,TA项目性能优化以及无关联需求的27个任务。总共修复 75个BUG。 需求号 _博客 2021年个人工作总结

VR制作中必须踩的坑365之019(oculus2、UE4、UE5、VR记录一年的踩坑之旅)Enumeration的状态的随机选择_ue5 enumeration_metagamer的博客-程序员宅基地

VR制作中必须踩的坑365之019(oculus2、UE4、UE5、VR记录一年的踩坑之旅)Enumeration的状态的随机选择Unreal Engine 4 - Quick! How to: Use enumshttps://www.youtube.com/watch?v=cdVjewFl7tQ&list=PLiVilLGZai7U9FBxfX9aJ9NkcfNHA3S7h&index=1https://www.youtube.com/watch?v=cdVjewFl7tQ&_ue5 enumeration

Python入门-环境搭建_python搭建环境搭建失败_天地炫舞的博客-程序员宅基地

本文介绍Python环境的搭建:(1)开发环境:Python3.5下载路径:https://www.python.org/downloads/release/python-354/(2)编辑器:Pycharm下载路径:http://www.downza.cn/soft/205725.html_python搭建环境搭建失败

随便推点

常见的Linux命令_suma h210 常见命令_这个手刹丿不太灵的博客-程序员宅基地

Linux常用命令1.ls(list)罗列出当前目录中的文件和目录,更常用的是ls -l/ll打印出更详细的信息2.cd(change dir)进入某个目录/切换到某个目录特殊的目录:a).表示当前目录b)… 表示当前目录的上级目录c) ~表示当前目录的家(home)目录d) /表示根目录 所有目录的最上级目录Linux的目录结构也是一种树形结构3.pwd查看当前目录的完整..._suma h210 常见命令

PyTorch学习笔记(3)--优化器Optim_optim选择_别管我啦就是说的博客-程序员宅基地

优化器Optim;SGD、RMSprop、Adagrad、Adadelta、Adam、Adamax_optim选择

11、【股票策略】用backtrader回测在A股上复利年化收益率超20%的“狗股策略”?_backtrader a股_云金杞的博客-程序员宅基地

11、用backtrader回测在A股上复利年化收益率超20%的“狗股策略”?1、什么是攻守兼备的“狗股策略”?​ 狗股理论是美国基金经理迈克尔·奥希金斯于1991年提出的一种投资策略。具体的做法是,投资者每年年底从道琼斯工业平均指数成份股中找出10只股息率最高的股票,新年买入,一年后再找出10只股息率最高的成分股,卖出手中不在名单中的股票,买入新上榜单的股票,每年年初年底都重复这一投资动作,便可获取超过大盘的回报。据有关统计,1975至1999年运用"狗股理论",投资的平均复利回报达18%,远高于市_backtrader a股

mysql乱码从解决到放弃_牧码文的博客-程序员宅基地

解决mysql的乱码问题由于中文字符的特殊性,选择不同的编码方式就会造成不用的结果,对于中文字符的处理一般都是使用utf8编码方式,在mysql中的乱码大概可以分为三种第一种:表的编码方式查看mysql中表的编码方式show create table table_name ;这里是我在创建表的时候有事先准备,默认应该是datian1字符集可以查看创建表的时候的编码方式,表的编码方式可以在创建表的时候指定create table table_name (name varchar(10

Android7.0以上自动安装软件_Superman.的博客-程序员宅基地

Android7.0发生了行为变更,禁止您的应用外部公开 file://Uri 。如果一项包含文件 Uri 的 Intent 离开您的应用后,则应用会出现故障,并出现 FileUriExposedException 异常。1.在AndroidManifest.xml中添加provider ,${applicationId}代表你的完成包名……2.在res下新建xml目录,新建f...

CopyOnWriteArrayList与Collections.synchronizedList的性能对比_Snowball的博客-程序员宅基地

列表实现有ArrayList、Vector、CopyOnWriteArrayList、Collections.synchronizedList(list)四种方式,其中

推荐文章

热门文章

相关标签