日常编程练习(三)

一、树的遍历算法

树的创建

struct BinaryTreeNode
{
    int val;
    BinaryTreeNode* left;
    BinaryTreeNode* right;
};

void creat_tree(BinaryTreeNode* &T)
{
    char a;
    cin>>a;
    if(a==‘#‘)
        T=NULL;
    else
    {
        T=new BinaryTreeNode;
        if(T==NULL)
            return;
        T->val=a-‘0‘;
        creat_tree(T->left);
        creat_tree(T->right);
    }
}

前序遍历

void pre_trave1(BinaryTreeNode* T)
{
    if(T==NULL)
        return;
    else
    {
        cout<<T->val<<" ";
        pre_trave1(T->left);
        pre_trave1(T->right);
    }
}

//非递归实现
void pre_trave2(BinaryTreeNode* T)
{
    if(T==NULL)
        return;
    stack<BinaryTreeNode*> st_T;
    while(1)
    {
        cout<<T->val;
        while(T)
        {
            if(T->right)
                st_T.push(T->right);   //先遍历左子树,遇到右子树入栈
            if(T->left)
                cout<<T->left->val;
            T=T->left;
        }
        if(!st_T.empty())
        {
            T=st_T.top();
            st_T.pop();
        }
        else
            break;
    }
}

中序遍历

void mid_trave1(BinaryTreeNode* T)
{
    if(T==NULL)
        return;
    else
    {
        mid_trave1(T->left);
        cout<<T->val<<" ";
        mid_trave1(T->right);
    }
}

//非递归实现
void mid_trave2(BinaryTreeNode* T)
{
    if(T==NULL)
        return;
    stack<BinaryTreeNode*> st_T;
    while(1)
    {
        while(T)
        {
            st_T.push(T);     //逢左子树入栈
            T=T->left;
        }
        if(!st_T.empty())
        {
            T=st_T.top();
            st_T.pop();
            cout<<T->val<<" ";
            T=T->right;
        }
        else
            break;
    }
}

后序遍历

//递归实现
void post_trave1(BinaryTreeNode* T)
{
    if(T==NULL)
        return;
    else
    {
        post_trave1(T->left);
        post_trave1(T->right);
        cout<<T->val<<" ";
    }
}
//非递归实现(破坏树的原结构)
void post_trave2(BinaryTreeNode* T)
{
    if(T==NULL)
        return;
    stack<BinaryTreeNode*> st_T;
    while(1)
    {
        while(T)
        {
            st_T.push(T);
            T=T->left;
        }
        if(!st_T.empty())
        {
            T=st_T.top();
            if(T->right)      //第一次经过根节点后打断与右子树的联系
            {
                BinaryTreeNode* temp=T->right;
                T->right=NULL;
                T=temp;
            }
            else
            {
                st_T.pop();
                cout<<T->val<<" ";
                T=NULL;
            }

        }
        else break;
    }
}
//非递归实现
void post_trave3(BinaryTreeNode* T)
{
    if(T==NULL)
        return;
    stack<BinaryTreeNode*> st_T;
    BinaryTreeNode* pre;
    while(1)
    {
        while(T)
        {
            st_T.push(T);
            T=T->left;
        }
        if(!st_T.empty())
        {
            T=st_T.top();
            if(T->right&&(pre!=T->right))  //当存在右子树且右子树没被打印时,先打印右子树
            {
               T=T->right;
            }
            else
            {
                pre=T;
                st_T.pop();
                cout<<T->val<<" ";
                T=NULL;
            }
        }
        else break;
    }
}

层序遍历

void level_trave(BinaryTreeNode* T)
{
    if(!T)
        return;
    queue<BinaryTreeNode*> qu_T;
    qu_T.push(T);
    while(!qu_T.empty())
    {
        BinaryTreeNode* temp=qu_T.front();
        qu_T.pop();
        if(temp->left!=NULL)
            qu_T.push(temp->left);
        if(temp->right!=NULL)
            qu_T.push(temp->right);
        cout<<temp->val<<" ";
    }
}

二、重建二叉树

问题描述:输入二叉树的前序与中序,输出重建的二叉树。

//很明显前序的首位是根结点,再从中序中查找根结点,就可以分为左右两个子树,依次递归可得。//递归条件和边界一定要分析清楚,不然很容易出错BinaryTreeNode* core_rebuild(vector<int>&,int,int,vector<int>&,int,int);
BinaryTreeNode* rebulid_bT(vector<int>& pre,vector<int>& mid,int length)
{
    if(!pre.size()||!mid.size()||length<=0)
    {
        return NULL;
    }
    return core_rebuild(pre,0,length-1,mid,0,length-1);
}

BinaryTreeNode* core_rebuild(vector<int>& pre,int pre_start,int pre_end,vector<int>& mid,int mid_start,int mid_end)
{
    BinaryTreeNode* root=new BinaryTreeNode;
    root->val=pre[pre_start];
    root->left=NULL;
    root->right=NULL;
    if(pre_start==pre_end)
    {
        return root;
    }
    int temp=mid_start;
    while(temp<=mid_end&&pre[pre_start]!=mid[temp])
        temp++;
    int count=temp - mid_start;
    if(count>0)    //temp不处于开始位置,则有左子树
        root->left=core_rebuild(pre,pre_start+1,pre_start+count,mid,mid_start,temp-1);
    if(temp!=mid_end)  //temp不处于终止位置,则有右子树
        root->right=core_rebuild(pre,pre_start+count+1,pre_end,mid,temp+1,mid_end);
    return root;
}

问题描述:输入二叉树的后序与中序,输出重建的二叉树。

BinaryTreeNode* core_rebuild2(vector<int>&,int,int,vector<int>&,int,int);
BinaryTreeNode* rebulid_bT(vector<int>& pre,vector<int>& mid,int length)
{
    if(!pre.size()||!mid.size()||length<=0)
    {
        return NULL;
    }
    return core_rebuild2(pre,0,length-1,mid,0,length-1);
}

BinaryTreeNode* core_rebuild2(vector<int>& post,int post_start,int post_end,vector<int>& mid,int mid_start,int mid_end)
{
    BinaryTreeNode* root=new BinaryTreeNode;
    root->val=post[post_end];
    root->left=NULL;
    root->right=NULL;
    if(post_start==post_end)
    {
        return root;
    }
    int temp=mid_start;
    while(post[post_end]!=mid[temp])
        temp++;
    int count=temp-mid_start;
    if(count>0)
        root->left=core_rebuild2(post,post_start,post_start+count-1,mid,mid_start,temp-1);
    if(temp<mid_end)
        root->right=core_rebuild2(post,post_start+count,post_end-1,mid,temp+1,mid_end);
    return root;
}
时间: 2024-10-20 03:00:16

日常编程练习(三)的相关文章

Linux - Unix环境高级编程(第三版) 代码编译

Unix环境高级编程(第三版) 代码编译 本文地址:http://blog.csdn.net/caroline_wendy 时间:2014.10.2 1. 下载代码:http://www.apuebook.com/code3e.html 2. 安装依赖库:sudo apt-get install libbsd-dev  3. 进入下载目录make 4. 复制头文件和动态链接库 sudo cp ./include/apue.h /usr/include/ sudo cp ./lib/libapue

【转】apue《UNIX环境高级编程第三版》第一章答案详解

原文网址:http://blog.csdn.net/hubbybob1/article/details/40859835 大家好,从这周开始学习apue<UNIX环境高级编程第三版>,在此,我要感谢网易的一个工程师朋友和室友,没有他们,我不会开始真正的学习这本书,希望大家以后开始慢慢进步.废话少说,直接上课后习题了. UNIX高级编程第一章习题答案: 1.1在系统上验证,除根目录外,目录l和l l是不同的. 答:这个验证有很多方法可使用命令ls .cd.vim等,目录.指向当前目录,目录..指

Java编程思想(三) —— 访问权限的控制

之前没去注意的修饰符,一般变量前面没添加,一个是不知道有什么用,一个是懒,后面遇到项目的时候就会发现私有和公有区别还是很大的. (1)首先是包名 使用一个类的时候,例如集合类,就需要引入这个包,然后再使用该包下面的类.如: package com.myown.iaiti; public class Print { static void print(String s){ System.out.println(s); } } 自定义的包,通过引入自己的包,以后你就可以使用自己写的方法进行字符串的打

【UNIX网络编程(三)】TCP客户/服务器程序示例

上一节给出了TCP网络编程的函数,这一节使用那些基本函数编写一个完成的TCP客户/服务器程序示例. 该例子执行的步骤如下: 1.客户从标准输入读入一行文本,并写给服务器. 2.服务器从网络输入读入这行文本,并回射给客户. 3.客户从网络输入读入这行回射文本,并显示在标准输出上. 用图描述如下: 编写TCP回射服务器程序如下: #include <stdio.h> #include <errno.h> #include <stdlib.h> #include <st

VS2013 MFC ODBC连接SQL SERVER数据库编程(三)

VS2013 MFC ODBC连接SQL SERVER数据库编程(三) 转载请注明:http://blog.csdn.net/my_acm/article/category/2616577 继上一篇讲完对数据库的链接以及一些说明之后,本文将实现对数据库的增删查改等操作. 如上图所示就是最终完成的一个简单的小程序. 首先添加列表框的NM_CLICK响应程序.鼠标放在列表框上,右键->添加事件处理程序,找到MN_CLICK消息,添加并编辑,如下图所示. 在响应函数里面添加如下代码: 这样就实现了,点

Unity3d 网络编程(三)(Unity3d内建网络简单服务器的建立)

使用Unity3d的内建网络搭建一个简单的服务器,使用本机当主机,创建一个客户端连接到本机, 我使用的NGUI作为主界面,服务器代码: string ipAddress = "127.0.0.1"; int port = 23000; string msg = ""; public UILabel lbl; // Use this for initialization void Start () { } // Update is called once per fr

嵌入式 Linux网络编程(三)——UDP编程模型

嵌入式 Linux网络编程(三)--UDP编程模型 UDP编程模型: UDP循环服务器模型为: socket(...); bind(...); while(1) {    recvfrom(...);    process(...);    sendto(...); } server.c代码: #include <stdio.h> #include <stdlib.h> #include <string.h> #include <unistd.h> #inc

unix环境高级编程(第三版)中apue.h文件的配置问题

最近刚开始学习unix环境高级编程(第三版),其中有个作者自己写的apue.h文件,在这归总下相应的配置方法,希望对有需要的朋友们有所帮助 首先http://www.apuebook.com/code3e.html 上去下载相应的压缩包,注意自己书的版本. 下载完成之后,鉴于大多数朋友学习linux都是基于虚拟机的,所以顺便附上虚拟机与本地主机传输文件的方式 首先下载SSH Secure Shell 这个工具,然后直接点击quick connect, 弹出如下界面,输入虚拟机的ip地址,和登录用

嵌入式 Linux系统编程(三)——标准IO库

嵌入式 Linux系统编程(三)--标准IO库 与文件IO函数相类似,标准IO库中提供的是fopen.fclose.fread.fwrite等面向流对象的IO函数,这些函数在实现时本身就要调用linux的文件IO这些系统调用. 一.标准IO库函数的缓冲机制 由于IO设备的访问速度与CPU的速度相差好几个数量级,为了协调IO设备与CPU的速度的不匹配,对于块设备,内核使用了页高速缓存,即数据会先被拷贝到操作系统内核的页缓存区中,然后才会从操作系统内核的缓存区拷贝到应用程序的地址空间. 当应用程序尝

javascript数据结构和算法 第一章(编程体验)三

变量作用域 变量作用域就是指在一个程序中,变量的值在哪里可以被获取到.javascript函数作用域被定义为函数作用域,这意味着变量的值在定义和声明该变量的函数,包括任何在该函数的嵌套函数里是可见的. 当一个变量定义在函数的外面,在主程序中,该变量将会拥有全局作用域.这就意味着它的值可以被程序的任何地方,包括函数获取. 下面的小程序演示全局变量时如何工作的. function showScope() { return scope; } var scope = "global"; pri