树-博客 0.PTA得分截图 1.本周学习总结(5分) 2.PTA实验作业(4分) 3.阅读代码(0--1分)

树-博客
0.PTA得分截图
1.本周学习总结(5分)
2.PTA实验作业(4分)
3.阅读代码(0--1分)

1.本周学习总结(5分)

树-博客
0.PTA得分截图
1.本周学习总结(5分)
2.PTA实验作业(4分)
3.阅读代码(0--1分)

1.1 二叉树结构

1.1.1 二叉树的2种存储结构

树-博客
0.PTA得分截图
1.本周学习总结(5分)
2.PTA实验作业(4分)
3.阅读代码(0--1分)

二叉树的顺序存储结构,指的是使用数组存储二叉树,但是需要注意的是顺序存储只适合用于存储完全二叉树。因此:如果我们想存储普通的二叉树,需要提前将普通二叉树转换为完全二叉树
顺序存储可能会浪费空间(在非完全二叉树的时候),但是读取某个指定的节点的时候效率比较高O(0)
树-博客
0.PTA得分截图
1.本周学习总结(5分)
2.PTA实验作业(4分)
3.阅读代码(0--1分)

从二叉树的顺序存储中可以看出,二叉树实际上不适合用数组进行存储,因为并不是每个二叉树都是完全二叉树,普通二叉树使用顺序表多少会存在浪费空间的现象,因此引入了二叉树的链式存储结构。
链式存储相对二叉树比较大的时候浪费空间较少,但是读取某个指定节点的时候效率偏低O(nlogn)

1.1.2 二叉树的构造

1.先序

BTree CreateBT(string str,int&i)
{
    if(i>=len-1)
        return NULL;
    if(str[i]=='#')
        return NULL;
        
     BTree bt=new BTnode;
     bt->data=str[i];
     bt->lchild=CreateBT(str,++i);
     bt->rchild=CreateBT(str,++i);
}

2.中序

BTree CreateBT(string str,int&i)
{
    if(i>=len-1)
        return NULL;
    if(str[i]=='#')
        return NULL;       
     BTree bt=new BTnode;   
     bt->lchild=CreateBT(str,++i);
     bt->data=str[i];
     bt->rchild=CreateBT(str,++i);
}
BTree CreateBT(string str,int&i)
{
    if(i>=len-1)
        return NULL;
    if(str[i]=='#')
        return NULL;       
     BTree bt=new BTnode;   
     bt->lchild=CreateBT(str,++i);     
     bt->rchild=CreateBT(str,++i);
     bt->data=str[i];
}

1.1.3 二叉树的遍历

1.先序遍历(DLR)

先序遍历的递归过程为:若二叉树为空,遍历结束。否则,

(1)访问根结点;
(2)先序遍历根结点的左子树;
(3)先序遍历根结点的右子树。

先序遍历二叉树的递归算法如下:

void PreOrder(BiTree bt)
{/*先序遍历二叉树bt*/
if (bt==NULL) return; /*递归调用的结束条件*/
Visite(bt->data); /*访问结点的数据域*/
PreOrder(bt->lchild); /*先序递归遍历bt 的左子树*/
PreOrder(bt->rchild); /*先序递归遍历bt 的右子树*/
}

2.中序遍历(LDR)
中序遍历的递归过程为:若二叉树为空,遍历结束。否则,
(1)中序遍历根结点的左子树;
(2)访问根结点;
(3)中序遍历根结点的右子树。

中序遍历二叉树的递归算法如下:

void InOrder(BiTree bt)
{/*中序遍历二叉树bt*/
if (bt==NULL) return; /*递归调用的结束条件*/
InOrder(bt->lchild); /*中序递归遍历bt 的左子树*/
Visite(bt->data); /*访问结点的数据域*/
InOrder(bt->rchild); /*中序递归遍历bt 的右子树*/
}

3.后序遍历(LRD)

后序遍历的递归过程为:若二叉树为空,遍历结束。否则,
(1)后序遍历根结点的左子树;
(2)后序遍历根结点的右子树。
(3)访问根结点;

后序遍历二叉树的递归算法如下:

void PostOrder(BiTree bt)
{/*后序遍历二叉树bt*/
if (bt==NULL) return; /*递归调用的结束条件*/
PostOrder(bt->lchild); /*后序递归遍历bt 的左子树*/
PostOrder(bt->rchild); /*后序递归遍历bt 的右子树*/
Visite(bt->data); /*访问结点的数据域*/
}

4.层次遍历
所谓二叉树的层次遍历,是指从二叉树的第一层(根结点)开始,从上至下逐层遍历,在同一层中,则按从左到右的顺序对结点逐个访问。对于图6.3(b)所示的二叉树,按层次遍历所得到的结果序列为:A B C D E F G

下面讨论层次遍历的算法。

由层次遍历的定义可以推知,在进行层次遍历时,对一层结点访问完后,再按照它们的访问次序对各个结点的左孩子和右孩子顺序访问,这样一层一层进行,先遇到的结点先访问,这与队列的操作原则比较吻合。因此,在进行层次遍历时,可设置一个队列结构,遍历从二叉树的根结点开始,首先将根结点指针入队列,然后从对头取出一个元素,每取一个元素,执行下面两个操作:
(1)访问该元素所指结点;
(2)若该元素所指结点的左、右孩子结点非空,则将该元素所指结点的左孩子指针和右孩子指针顺序入队。

此过程不断进行,当队列为空时,二叉树的层次遍历结束。在下面的层次遍历算法中,二叉树以二叉链表存放,一维数组Queue[MAXNODE]用以实现队列,变量front 和rear 分别表示当前对首元素和队尾元素在数组中的位置。

void LevelOrder(BiTree bt)
/*层次遍历二叉树bt*/
{ BiTree Queue[MAXNODE];
int front,rear;
if (bt==NULL) return;
front=-1;
rear=0;
queue[rear]=bt;
while(front!=rear)
{front++;
Visite(queue[front]->data); /*访问队首结点的数据域*/
if (queue[front]->lchild!=NULL) /*将队首结点的左孩子结点入队列*/
{ rear++;
queue[rear]=queue[front]->lchild;
}
if (queue[front]->rchild!=NULL) /*将队首结点的右孩子结点入队列*/
{ rear++;
queue[rear]=queue[front]->rchild;
}
}
}

1.1.4 线索二叉树

在普通二叉树中,我们想要获取某个结点在某种遍历次序下的直接前驱或后继,每次都需要遍历获取到遍历次序之后才能知道。而在线索二叉树中,我们只需要遍历一次(创造线索二叉树时的遍历),之后,线索二叉树就能“记住”每个结点的直接前驱和后继了,以后都不需要再通过遍历次序获取前驱或后继了。
树-博客
0.PTA得分截图
1.本周学习总结(5分)
2.PTA实验作业(4分)
3.阅读代码(0--1分)

我们按照某种遍历方式,把普通二叉树变为线索二叉树的过程被称为二叉树的线索化。

1.1.5 二叉树的应用--表达式树

/*先将中缀表达式转换为后缀表达式*/
定义栈ope存放运算符 定义字符数组newstr存放后缀表达式 i为下标
字符c为str[i]
while c不为' '
    if c是数字 then
        直接入newstr字符数组
   else if c是右括号 then
        出栈到newstr字符数组至栈顶为左括号
    else if 是左括号
        全部入栈直至右括号
    else
        if 优先级大于栈顶 then
            全部出栈后入栈
        else
            入栈
        end if
    end if
end while
/*得到后缀表达式newstr*/
/*递归建树*/
定义树结点栈BT和数字字符栈num
i为下标 
while遍历后缀表达式
    if当前为数字 then
        入数字栈num
    else if当前树节点栈恰好有两个操作数 then
        建立一颗子树
        子树根入栈
    else if
        当前为操作符且数字栈数字大于两个
        建立一个树节点并入BT栈
    end if
end while
/*计算表达式树*/
定义result为记录当前树的结果
if 此时结点T为空 递归到此结束返回
else 
    if 此时为叶子节点 then 
        返回叶子节点的数值
    else if 此时为操作符号 
        根据操作符递归返回其左右孩子的结果
    end if
end if 

1.2 多叉树结构

1.2.1 多叉树结构

树-博客
0.PTA得分截图
1.本周学习总结(5分)
2.PTA实验作业(4分)
3.阅读代码(0--1分)

1.2.2 多叉树遍历

1.3 哈夫曼树

1.3.1 哈夫曼树定义

树-博客
0.PTA得分截图
1.本周学习总结(5分)
2.PTA实验作业(4分)
3.阅读代码(0--1分)

树-博客
0.PTA得分截图
1.本周学习总结(5分)
2.PTA实验作业(4分)
3.阅读代码(0--1分)

1.3.2 哈夫曼树的结构体

typedef struct{
	int weight;
	int parent,lchild,rchild;
}HTNode char *HuffmanTree;      //动态分配数组存储哈夫曼树
typedef char * *HuffmanCode;    //动态分配数组存储哈夫曼树编码表 

1.3.3 哈夫曼树构建及哈夫曼编码

结合一组叶子节点的数据,介绍如何构造哈夫曼树及哈夫曼编码。

1.4 并查集

树-博客
0.PTA得分截图
1.本周学习总结(5分)
2.PTA实验作业(4分)
3.阅读代码(0--1分)

并查集:(union-find sets)是一种简单的用途广泛的集合. 并查集是若干个不相交集合,能够实现较快的合并和判断元素所在集合的操作,应用很多,如其求无向图的连通分量个数、最小公共祖先、带限制的作业排序,还有最完美的应用:实现Kruskar算法求最小生成树。

1.5.谈谈你对树的认识及学习体会。

2.PTA实验作业(4分)

2.1 二叉树

二叉树叶子结点带权路径长度和>代码地址(https://gitee.com/lin-dachun/code/blob/master/二叉树叶子结点带权路径长度和)

2.1.1 解题思路及伪代码

2.1.2 总结解题所用的知识点

2.2 目录树

2.2.1 解题思路及伪代码

2.2.2 总结解题所用的知识点

3.阅读代码(0--1分)

找1份优秀代码,理解代码功能,并讲出你所选代码优点及可以学习地方。主要找以下类型代码:

3.1 题目及解题代码

可截图,或复制代码,需要用代码符号渲染。

3.2 该题的设计思路及伪代码

请用图形方式展示解决方法。同时分析该题的算法时间复杂度和空间复杂度。

3.3 分析该题目解题优势及难点。