数据结构学习笔记(五) 树的创建和遍历

创建(先序创建和根据先序和中序进行创建)和遍历(先序遍历、中序遍历、后序遍历、非递归堆栈遍历、层次遍历):

  

package tree;

public class XianCreateTree {
    private static Node header;
    //非递归遍历的堆栈头指针
    private static Node first;
    //层次遍历的尾和头指针(队尾插入,对头出去)
    private static Node rear;
    private static Node front;
    private static int i;
    public static void main(String[] args) {   //这是先序创建
    //    char[] tree = new char[]{‘A‘,‘B‘,‘C‘,‘*‘,‘*‘,‘D‘,‘*‘,‘*‘,‘E‘,‘*‘,‘F‘,‘G‘,‘*‘,‘*‘,‘*‘};
    //    createTree(tree);

        char[] pre = new char[]{‘A‘,‘B‘,‘C‘,‘D‘,‘E‘,‘F‘,‘G‘};
        char[] mid = new char[]{‘C‘,‘B‘,‘D‘,‘A‘,‘E‘,‘G‘,‘F‘};
        header = new Node(pre[0]);
        preMid(pre,mid,header);
        System.out.print("先序遍历:");
        preTraverse(header);
        System.out.println();
        System.out.print("中序遍历:");
        midTraverse(header);
        System.out.println();
        System.out.print("后序遍历:");
        afterTraverse(header);
        System.out.println();//非递归遍历和层次遍历不能一起执行,因为都有next
//        System.out.print("非递归历:");
//        noRecursion(header);
//        System.out.println();
        System.out.print("层次遍历:");
        queue(header);
        System.out.println();
    }

    /*
     * 先序创建一棵二叉树
     */
    public static Node createTree(char[] tree){
        if(tree[i] == ‘*‘){
            return null;
        }
        Node node = new Node(tree[i]);
        if(header == null){
            header = node;
        }
        i++;
        node.left=createTree(tree);
        i++;
        node.right=createTree(tree);
        return node;
    }
    /**
     * 先 和 中创建一棵二叉树
     */
    public static Node preMid(char[] pre,char[] mid,Node node){
        int index  = getIndex(mid,node.data);
        //说明还有右子树
        int len = pre.length-1-index;

        char[] pre_left;
        char[] pre_right;
        char[] mid_left;
        char[] mid_right;
        if(index > 0){
            if(index == 1){
                node.left = new Node(mid[0]);
            }else{
                pre_left = new char[index];
                mid_left = new char[index];
                //arg0:源数组;arg1:源数组要复制的起始位置;arg2:目的数组;arg3:目的数组放置的起始位置;rg4:复制的长度。
                System.arraycopy(pre, 1, pre_left, 0, index);
                System.arraycopy(mid, 0, mid_left, 0, index);
                //找到根节点后的第一个节点
                //找到根节点后的第一个节点在中序的位置
                node.left = preMid(pre_left,mid_left,new Node(pre_left[0]));
            }
        }
        if(len > 0){
            if(len == 1){
                node.right = new Node(mid[index+1]);
            }else{
                pre_right = new char[len];
                mid_right = new char[len];
                System.arraycopy(pre, index+1, pre_right, 0, mid.length-index-1);
                System.arraycopy(mid, index+1, mid_right, 0, mid.length-index-1);
                node.right = preMid(pre_right,mid_right,new Node(pre_right[0]));
            }
        }
        return node;
    }
    public static int getIndex(char[] mid,char c){
        for (int i = 0; i < mid.length; i++) {
            if(mid[i] == c){
                return i;
            }
        }
        return -1;
    }
    /**
     * 先序遍历
     */
    public static Node preTraverse(Node node){
        if(node != null){
            System.out.print(node.data+" ");
            node.left = preTraverse(node.left);
            node.right = preTraverse(node.right);
        }
        return node;
    }

    /**
     * 中序遍历
     */
    public static Node midTraverse(Node node){
        if(node != null){
            node.left = midTraverse(node.left);
            System.out.print(node.data+" ");
            node.right = midTraverse(node.right);
        }
        return node;
    }

    /**
     * 后序遍历
     */
    public static Node afterTraverse(Node node){
        if(node != null){
            node.left = afterTraverse(node.left);
            node.right = afterTraverse(node.right);
            System.out.print(node.data+" ");
        }
        return node;
    }
    /*
     * 使用堆栈(堆栈里存放的是节点)非递归遍历(中序)
     */
    public static void noRecursion(Node node){
        first = new Node(‘o‘);
        //右子树
        while(node != null || first.next != null){
            //左子树
            while(node != null){
                //System.out.print(first.next.data +" ");先序
                node.next = first.next;
                first.next = node;
                node = node.left;
            }
            if(first.next != null){
                System.out.print(first.next.data +" ");
                node = first.next;
                first.next = first.next.next;
                node = node.right;
            }
        }
    }
    /**
     * 使用队列层次遍历
     */
    public static void queue(Node node){
        rear = front = node;
        while(front != null){
            if(front.left != null){
                rear.next = front.left;
                rear = rear.next;
            }
            if(front.right != null){
                rear.next = front.right;
                rear = rear.next;
            }
            System.out.print(front.data+" ");
            front = front.next;
        }
    }
}

  

树的结点类:

  

package tree;

public class Node {
    public char data;
    public Node left;
    public Node right;
    public Node next;
    public Node(char data) {
        super();
        this.data = data;
    }

}
时间: 2024-10-30 07:24:42

数据结构学习笔记(五) 树的创建和遍历的相关文章

小猪的数据结构学习笔记(五)

小猪的数据结构学习笔记(五) 线性表之--循环链表                           --转载请注明出处:coder-pig 循环链表知识点归纳: 相关代码实现: ①判断是否为空表: ②单循环链表的存储结构 其实和单链表的结构是一样的! /*定义循环链表的存储结构*/ typedef struct Cir_List { int data; struct Cir_List *next; }Lnode; ③初始化循环单链表 代码如下: //1.循环链表的初始化 //表示一个元素,如

数据结构学习笔记(树、二叉树)

树(一对多的数据结构) 树(Tree)是n(n>=0)个结点的有限集.n=0时称为空树.在任意一颗非空树种: (1)有且仅有一个特定的称为根(Root)的结点: (2)当n>1时,其余结点可分为m(m>0)个互不相交的有限集T1.T2........Tn,其中每一个集合本身又是一棵树,并且称为根的子树. 对于树的定义还需要强调两点:1.n>0时根结点是唯一的,不可能存在多个根结点,数据结构中的树只能有一个根结点.2.m>0时,子树的个数没有限制,但它们一定是互不相交的. 结点

数据结构学习笔记04树(堆 哈夫曼树 并查集)

一.堆(heap) 优先队列(Priority Queue):特殊的“队列”,取出元素的顺序是依照元素的优先权(关键字)大小,而不是元素进入队列的先后顺序. 数组 : 插入 — 元素总是插入尾部 ~ O ( 1 ) 删除 — 查找最大(或最小)关键字 ~ O ( n ) 从数组中删去需要移动元素 ~ O( n ) 链表: 插入 — 元素总是插入链表的头部 ~ O ( 1 ) 删除 — 查找最大(或最小)关键字 ~ O ( n ) 删去结点 ~ O( 1 ) 有序数组: 插入 — 找到合适的位置

数据结构学习笔记04树(二叉树、二叉搜索树、平衡二叉树)

一.树 树的基本术语 ①结点的度(Degree):结点的子树个数 ②树的度:树的所有结点中最大的度数 ③叶结点(Leaf):度为0的结点 ④父结点(Parent):有子树的结点是其子树的根结点的父结点 ⑤子结点(Child):若A结点是B结点的父结点,则称B结点是A结点的子结点:子结点也称孩子结点. ⑥兄弟结点(Sibling):具有同一父结点的各结点彼此是兄弟结点. ⑦路径和路径长度:从结点n1到nk的路径为一个结点序列n1 , n2 ,… , nk , ni是 ni+1的父结点.路径所包含边

小猪的数据结构学习笔记(二)

小猪的数据结构学习笔记(二) 线性表中的顺序表 本节引言: 在上个章节中,我们对数据结构与算法的相关概念进行了了解,知道数据结构的 逻辑结构与物理结构的区别,算法的特性以及设计要求;还学了如何去衡量一个算法 的好坏,以及时间复杂度的计算!在本节中我们将接触第一个数据结构--线性表; 而线性表有两种表现形式,分别是顺序表和链表;学好这一章很重要,是学习后面的基石; 这一节我们会重点学习下顺序表,在这里给大家一个忠告,学编程切忌眼高手低,看懂不代表自己 写得出来,给出的实现代码,自己要理解思路,自己

NLTK学习笔记(五):分类和标注词汇

[TOC] 词性标注器 之后的很多工作都需要标注完的词汇.nltk自带英文标注器pos_tag import nltk text = nltk.word_tokenize("And now for something compleyely difference") print(text) print(nltk.pos_tag(text)) 标注语料库 表示已经标注的标识符:nltk.tag.str2tuple('word/类型') text = "The/AT grand/J

【数据结构学习笔记(C#描述)】(二)算法分析

由上一章的内容可知软件质量的重要特征之一就是能够高效的利用资源(运行效率),因此我们就要考虑如何创建出能够高效利用CPU及内存的数据结构与算法.而算法分析的目的就是为了让我们能够认识到算法对于资源的利用效率. 我们要想分析算法的效率,就需要找到一个评价算法效率的标准及方法. 一般我们如果能快速的利用CPU就会更好的节省时间,因此在时间层面上我们的评价标准就是时间复杂度,而如果我们能够较好的利用内存的话我们将会节省更多的内存空间,因此在空间层面上我们的评价标准就是空间复杂度. 所谓时间复杂度和空间

数据结构学习笔记——线性表的应用

数据结构学习笔记——线性表的应用 线性表的应用 线性表的自然连接 计算任意两个表的简单自然连接过程讨论线性表的应用.假设有两个表A和B,分别是m1行.n1列和m2行.n2列,它们简单自然连接结果C=A*B(i==j),其中i表示表A中列号,j表示表B中的列号,C为A和B的笛卡儿积中满足指定连接条件的所有记录组,该连接条件为表A的第i列与表B的第j列相等. 如:         1 2 3                3 5 A  =  2 3 3         B =  1 6       

Boost Thread学习笔记五

多线程编程中还有一个重要的概念:Thread Local Store(TLS,线程局部存储),在boost中,TLS也被称作TSS,Thread Specific Storage.boost::thread库为我们提供了一个接口简单的TLS的面向对象的封装,以下是tss类的接口定义: class tss{public:    tss(boost::function1<void, void*>* pcleanup);    void* get() const;    void set(void*

深度学习笔记(五):LSTM

深度学习笔记(一):logistic分类 深度学习笔记(二):简单神经网络,后向传播算法及实现 深度学习笔记(三):激活函数和损失函数 深度学习笔记(四):循环神经网络的概念,结构和代码注释 深度学习笔记(五):LSTM 看到一篇讲LSTM非常清晰的文章,原文来自Understanding LSTM Networks , 译文来自理解LSTM网络 Recurrent Neural Networks 人类并不是每时每刻都从一片空白的大脑开始他们的思考.在你阅读这篇文章时候,你都是基于自己已经拥有的