3.1 树与树的表示

3.1.1 查找的方法


方法1: 顺序查找(时间复杂度为 O(n) );
//在数组的头部,建立哨兵,可减少判断的分支。

3.1.2 树


定义: nn0 个结点构成的有限集合。
- 当 n=0 时,称为 空树 ;
-树中有一个称为“ 根(Root ) ”的特殊结点, 用 r 表示;
- 其余结点可分为m(m>0) 个 互不相交的 有限集,其中每个集合本身又是一棵树,称为原来树的“ 子树 (SubTree )”。






儿子-兄弟表示法
所需的总空间为 3N (N为节点数)。

3.2 二叉树及存储结构


定义:一个有穷的结点集合。
- 这个集合 可以为空;
- 若不为空,则它是由 根结点 和称为其 左子树 TL 右子树 TR 的两个不相交的二叉树组成。



  1. 顺序存储(主要针对 );

  2. 链式存储


typedef struct PloyNode *polynomial;//这句有什么用呢?
typedef struct polyNode{//这两个typedef有什么联系吗?
int coef;
int expon;
polynomial link;//这里是定义了一个相当于next后继指针吗?
}
如果按这样定义好了之后,如何定义一个这样的链表?

:
1. typedef struct PloyNode *polynomial;
这句是说:定义了一个结构体变量的指针,以后你可以直接用polynomial来代表struct polyNode *这个数据.
2. typedef struct polyNode{
int coef;
int expon;
polynomial link; }

这个也是一个定义,定义了一个结构体变量,简化了结构体变量的定义。你可以用polyNode来代表整个结构体变量。

再来说一下他们之间的联系: 第一个是定义的一个简化的指针变量:struct polyNode * ; 第二个定义了一个简化的结构体变量polyNode来代替:typedef struct polyNode;

综上是否可理解为:指针变量polynomial具有结构体polyNode的结构,即L=(polynomial)malloc(sizeof(polyNode))这样就生成一个新的PloyNode结点。

3.3 二叉树的遍历

运用递归函数进行遍历




    • 三种遍历算法的遍历路径是一样的,只是访问各节点的时机不同。
  1. 非递归遍历(使用堆栈)

  2. 层序遍历(使用队列)

例1:输出二叉树中的 叶子结点。

例2. 求二叉树的高度

例3. 由 任意两种 遍历序列确定二叉树,对么?(其中一个必须是中序遍历)

3.4 小白专场:树的同构

程序:

//输入样例1(对应图1):
//
//8
//A 1 2
//B 3 4
//C 5 -
//D - -
//E 6 -
//G 7 -
//F - -
//H - -
//8
//G - 4
//B 7 6
//F - -
//A 5 1
//H - -
//C 0 -
//D - -
//E 2 -
//输出样例1:
//
//Yes

//输入样例2(对应图2):
//
//8
//B 5 7
//F - -
//A 0 3
//C 6 -
//H - -
//D - -
//G 4 -
//E 1 -
//8
//D 6 -
//B 5 -
//E - -
//H - -
//C 0 2
//G - 3
//F - -
//A 1 4
//输出样例2:
//
//No
//给定两棵树T1和T2。如果T1可以通过若干次左右孩子互换就变成T2,则我们称两棵树是“同构”的。
//author: Paul-Huang
//data: 18/6/2017

#include<stdio.h>
#include <stdlib.h>
#include<process.h>//引入头文件

#define MaxTree 10
#define Null -1 
#define ElementType char 
#define Tree int

//建立动态链表
struct TreeNode
{
    ElementType node;
    Tree Left;
    Tree Right;
}Tree1[MaxTree],Tree2[MaxTree];

Tree BuildTree(struct TreeNode T[]);
int Isomprphic(Tree root1,Tree root2);

int main()
{
    Tree R1,R2;
    R1 = BuildTree(Tree1);
    R2 = BuildTree(Tree2);
    if (Isomprphic(R1,R2)){
        printf("Yes\n");
    }
    else{
        printf("No\n");
    }

    system("pause");//暂停往下执行 按下任意键继续
    return 1;
}

Tree BuildTree(struct TreeNode T[])
{
    Tree check[MaxTree],Root = Null; //root = Null 空树则返回Null
    char cl,cr; 
    int i,N;
    scanf("%d\n",&N);
    if (N) {
        for ( i = 0; i < N; i++)
            check[i] = 0;
        //输入数值,并建立链表
        for (i = 0; i < N; i++)
        {
            scanf("%c %c %c\n",&T[i].node,&cl,&cr);
            if (cl != '-'){
                T[i].Left = cl - '0';
                check[T[i].Left] = 1;
            }
            else{
                T[i].Left = Null;
            }
            if (cr != '-'){
                T[i].Right = cr - '0';
                check[T[i].Right] = 1;
            }
            else{
                T[i].Right = Null;
            }
        }
        //查找二叉树的根
        for (i = 0; i < N; i++)
            if (!check[i])
                break;
        Root = i;
    }
    return Root;

}


int Isomprphic(Tree root1,Tree root2)
{
    if ((root1 == Null) && (root2 == Null))/* both empty */
        return 1;
    if (((root1 == Null) && (root2 != Null)) || ((root1 != Null) && (root2 == Null)))
        return 0;/* one of them is empty */

    if (Tree1[root1].node != Tree2[root2].node)
        return 0; /* roots are different */

    if ((Tree1[root1].Left == Null) && (Tree2[root2].Left == Null))
        /* both have no left subtree */
        return Isomprphic(Tree1[root1].Right,Tree2[root2].Right);

    if ((Tree1[root1].Right == Null) && (Tree2[root2].Right == Null))
        /* both have no right subtree */
        return Isomprphic(Tree1[root1].Left,Tree2[root2].Left);

    if ((Tree1[root1].Left != Null) && (Tree2[root2].Left != Null) &&
        ((Tree1[Tree1[root1].Left].node) == (Tree2[Tree2[root2].Left].node)))
        /* no need to swap the left and the right */
        return (Isomprphic(Tree1[root1].Left,Tree2[root2].Left)&&
        Isomprphic(Tree1[root1].Right,Tree2[root2].Right));
    else/* need to swap the left and the right */
        return (Isomprphic(Tree1[root1].Left,Tree2[root2].Right) &&
            Isomprphic(Tree1[root1].Right,Tree2[root2].Left));

}

陈越《数据结构》第三讲 树上的更多相关文章

  1. 初识Swift集合之字典集合

    这个函数也会返回被替换或者增加的值。

  2. swift的一些知识点演练

    表示可以有值,也可以没有值//?如果对象为空,就不会调用后面的方法,感觉上和oc中给nil发送消息类似varstr:Nsstring?str="hello"//打印可选项的时候,同时会输出一个Optional,提示开发者,这是一个可选项println(str?.length)letl=10//目前的代码存在什么风险?如果str没有设置初始值,会直接崩溃//苹果把判断对象是否有内容的工作交给了程序员//letlen=l+str!用来快速判断对象是否为nilletlen2=l+(str?0)//以下代码和上面

  3. swift 基础笔记四数组

  4. swift篇第一期:简单的数据结构

    首先我们可以去使用Playground来编码,并且会实时的显示对应的编码信息,这样我们就不用每次都去运行程序来显示输出的东西了哦,也方便了我们对某些语句的验证,这个是比较赞的var与let前者为可变修饰符,后者为不可变从字面意思我们就可以很好的区分了常用的类型呢,跟其他语言基本相同啦,主要有几种:1.int类型2.Float,Double类型3.String类型4.Boolean类型当我们去声明一

  5. Swift值字典使用

    字典是一种用来存放相同类型的数据项的集合。Swift中字典的概念和现实世界中的字典的概念很相似,都是通过索引来查里面特定的值。修改一个值5、删除字典键值对四、字典遍历同数组一样,字典遍历也需要使用forin循环。

  6. Swift学习笔记十三——区间运算符和for-in循环

    区间运算符RangeOperator也是Swift的一个比较突出的特点。可以用来表示一段数据的区域。区间运算符主要可以分为以下两类:ClosedRangeOperator:闭区间[a,b]a...b:注意:a和b之间是三个点Half-ClosedRangeOperator:前闭后开区间a..

  7. Swift遍历数组的三种方式

    1.forindexin0..

  8. Swift入门五——数组Array

    集合集合的定义Swift中提供了两种数据结构用于存放数据的集合,分别是数组和字典。一共有三种方法来定义数组的类型:第一种是数组类型的完整定义,即Array关键字加上一对尖括号,括号内写上数组元素的类型。1]其实是一个SubArray,在Swift中它的类型叫做ArraySlice,即Int类型的数组切片,而右边是一个Array类型变量,根据Swift类型安全的特性,这样的操作自然是被禁止的。

  9. swift-07-使用for-in 遍历数组

    //for-in/*for迭代变量in集合变量{使用迭代变量便利所有数据}*///遍历数组vararr=["a","b","c","d"]fortempinarr{printprint}//vararray:[]=[,("王三",30,("张浩",50,"女")]forvinarr{ifv.0=="王三"{print(v)break}}

  10. Swift 字典的常用方法

    /***要正确使用字典,也需要一些条件*1,字典键值对的键和值的类型必须明确,可以直接指定,也可以类似数组直接赋值由编译器自动识别*2,字典必须要初始化*3,键的类型必须是可以被哈希Hashable的**///字典的几种声明方式常用方法见下方代码苹果开发群:414319235欢迎加入欢迎讨论

随机推荐

  1. 【数据结构】单调栈

    显然,每个发射站发来的能量有可能被0或1或2个其他发射站所接受,特别是为了安全,每个发射站接收到的能量总和是我们很关心的问题。由于数据很多,现只需要你帮忙计算出接收最多能量的发射站接收的能量是多少。输入输出格式输入格式:第1行:一个整数N;第2到N+1行:第i+1行有两个整数Hi和Vi,表示第i个人发射站的高度和发射的能量值。输入输出样例输入样例:34235610输出样例:7题解中有讲解代码实现

  2. BZOJ 1798 [Ahoi2009] Seq 维护序列seq [线段树+多重标记下传]【数据结构】

    有长为N的数列,不妨设为a1,a2,…Input第一行两个整数N和P。第二行含有N个非负整数,从左到右依次为a1,aN,。表示把所有满足t≤i≤g的ai改为ai×c。操作2:“2tgc”。同一行相邻两数之间用一个空格隔开,每行开头和末尾没有多余空格。Output对每个操作3,按照它在输入中出现的顺序,依次输出一行一个整数表示询问结果。SampleInput7431234567512553242379313347SampleOutput2358HINT初始时数列为。对第5次操作,和为29+34+15+16=

  3. 陈越《数据结构》第一讲 基本概念

    陈越《数据结构》第一讲基本概念1什么是数据结构1.1引子例子:如何在书架上摆放图书?数据结构是:1.数据对象在计算机中的组织方式;2.数据对象必定与一系列加在其上的操作相关联;3.完成这些操作所用的方法就是算法。抽象数据类型数据类型-数据对象集;-数据集合相关联的操作集。抽象-与存放数据的机器无关;-与数据存储的物理结构无关;-与实现操作的算法和编程语言均无关。

  4. 陈越《数据结构》第二章 线性结构

    表中元素个数称为线性表的长度;线性表没有元素时,称为空表;表起始位置称表头,表结束位置称表尾。插入和删除操作只能在链栈的栈顶进行。

  5. 【数据结构】

    非线性结构:线性结构的元素之间具有线性关系,非线性结构中的元素之间不再是序列的关系,他们呈现的是更复杂的层次关系,即一个数据元素有且仅有一个直接前驱,但可有另个或者多个直接后继,显然比序列关系复杂常见非线性结构:树,图散列表PHP中的hashtable就是哈希表就是由数组和链表组成,一个长度为16的数组中,每个元素存储的是一个链表的头结点。

  6. 【数据结构】【C++STL】FIFO队列&amp;优先队列

    首先都需要打头文件queueFIFO队列是先进先出的就好像排队一样STL定义FIFO队列优先队列的话是有优先级存在的STL定义优先队列定义方式都是大根堆FIFO队列和优先队列都有一些操作COYG

  7. 【数据结构】 堆

    自底向上://增加/减少已有节点值Heap_Increase_Key//向堆插入新的节点HeapInsert自顶向下://替换堆顶后,维持堆函数KeepHeap//弹出堆顶函数Pop

  8. 【数据结构】链表

    线性表的顺序存储结构有存储密度高及能够随机存取等优点,但存在以下不足:线性表的链式存储(单链表)的实现单向循环链表的实现

  9. 伸展树(SPLAY)个人总结+模板 [平衡树]【数据结构】【模板】

    前言最近3个月内,无论是现场赛还线上赛中SPLAY出现的概率大的惊人啊啊啊!!!然而不会的我就GG了,同时发现大家都会SPLAY,,,,然后就学习了一波。——————————————————————————-附上整体代码-md贴上来太卡了,去题解里看吧维护序列的维护一堆数的

  10. BZOJ 1895 &amp; POJ 3580 supermemo [SPLAY]【数据结构】

    Ay}Ttimes.Forexample,performing“REVOLVE242”on{1,5}INSERTxP:insertPafterAx.Forexample,performing“INSERT24”on{1,5}DELETEx:deleteAx.Forexample,performing“DELETE2”on{1,5}MINxy:querytheparticipantwhatistheminimumnumberinsub-sequence{Ax…Ay}.Forexample,thecorrec

返回
顶部