# 1.本周学习总结

## 二叉树

### 先序遍历递归建树

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


### 根据中序序列和后序序列建树

BTree CreateBTree(char inOd[], char postOd[], int n)
{
if (n == 0)
return NULL;

BTree btRoot = new BTNode;
btRoot->data = postOd[n-1];     //后序序列最后一个元素一定是根节点
char lInOd[N], rInOd[N];
char lPostOd[N], rPostOd[N];
int n1, n2;
n1 = n2 = 0;
//根据根节点将中序序列分为左子树和右子树
for (int i = 0; i < n; i++)
{
if (i <= n1 && inOd[i] != btRoot->data)
lInOd[n1++] = inOd[i];
else if (inOd[i] != postOd[n-1])
rInOd[n2++] = inOd[i];
}
//根据一个树的后序序列的长度等于中序序列且后序遍历是先左子树再右子树
//将后序序列分为左子树和右子树
int m1, m2;
m1 = m2 = 0;
for (int i = 0; i < n-1; i++)
{
if (i < n1)
lPostOd[m1++] = postOd[i];
else
rPostOd[m2++] = postOd[i];
}
btRoot->lChild = CreateBTree(lInOd, lPostOd, n1);
btRoot->rChild = CreateBTree(rInOd, rPostOd, n2);
return btRoot;
}


### 前序遍历

void PreOrder(BTreeNode* BT) {
if(BT != NULL) {
cout << BT->data << ' ';     //访问根结点
PreOrder(BT->left);          //前序遍历左子树
PreOrder(BT->right);         //前序遍历右子树
}
}


### 中序遍历

void InOrder(BTreeNode* BT) {
if(BT != NULL) {
InOrder(BT->left);          //中序遍历左子树
cout << BT->data << ' ';    //访问根结点
InOrder(BT->right);         //中序遍历右子树
}
}


### 后序遍历

void PostOrder(BTreeNode* BT) {
if(BT != NULL) {
PostOrder(BT->left);        //后序遍历左子树
PostOrder(BT->right);       //后序遍历右子树
cout << BT->data << ' ';    //访问根结点
}
}


### 层次遍历

void AllPath2(BTree b)
{
int k;
BTree p;
QuType *qu;		    //定义非非环形队列指针
InitQueue(qu);		    //初始化队列
b->parent=-1;   //创建根结点对应的队列元素
enQueue(qu，b);		    //根结点进队
while (!QueueEmpty(qu))	//队不空循环
{
deQueue(qu，p);	//出队
if (p->lchild==NULL && p->rchild==NULL)
{
k=qu->front;	//输出结点p到根结点的路径逆序列
while (qu->data[k]->parent!=-1)
{
printf("%c->"，qu->data[k]->data);
k=qu->data[k]->parent;
}
printf("%c\n"，qu->data[k]->data);
}
}
}


## 树

### 双亲存储结构

typedef struct
{　 ElemType data;	//结点的值
int parent;		//指向双亲的位置
} PTree[MaxSize];


### 孩子链存储结构

typedef struct node
{      ElemType data;		  //结点的值
struct node *sons[MaxSons];	      //指向孩子结点
}  TSonNode;


### 孩子兄弟链存储结构

typedef struct tnode
{      ElemType data;	//结点的值
struct tnode *son;  	//指向兄弟
struct tnode *brother;  //指向孩子结点
} TSBNode;


## 线索二叉树

n个结点的二叉链表共有2n个链域，非空链域为n-1个，但其中的空链域却有n+1个。

## 哈夫曼树

### 构造哈夫曼树

1、根据给定的n个权值{w1, w2, w3 ... wn }，构造n棵只有根节点的二叉树，令起权值为wj
2、在森林中选取两棵根节点权值最小的树作为左右子树，构造一颗新的二叉树，置新二叉树根节点权值为其左右子树根节点权值之和。左子树的权值应小于右子树的权值
3、从森林中删除这两棵树，同时将新得到的二叉树加入森林中（换句话说，之前的2棵最小的根节点已经被合并成一个新的结点了）
4、重复上述两步，直到只含一棵树为止，即哈夫曼树

# 2.阅读代码

## 2.1 二叉树最大宽度

int widthOfBinaryTree(TreeNode* root)
{
int ans = 0;
deque<TreeNode*> dque;
TreeNode* tmp = NULL;

if(root == NULL) return ans;
dque.push_back(root);
while(!dque.empty())
{
// 出队前需要判断队列是否为空.
while(!dque.empty()&&dque.front() == NULL) dque.pop_front();
while(!dque.empty()&&dque.back() == NULL) dque.pop_back();
int n = dque.size();
if(n == 0) break;
ans = max(ans, n);
for(int i = 0; i < n; ++i){
tmp = dque.front();dque.pop_front();
dque.push_back(tmp == NULL ? NULL:tmp->left);
dque.push_back(tmp == NULL ? NULL:tmp->right);
}
}
return ans;
}


### 2.1.1 设计思路

null指针的左右两个儿子均为null。

### 2.1.2 伪代码

int widthOfBinaryTree(TreeNode* root)
{
整型变量ans记录层宽度，初始化为0
定义双端队列dque
定义一个空指针tmp
if(空树)
return ans;
根节点入队
while(队列不空)
{
while(队列不空且dque的队头为NULL)  队头出队;
while(队列不空且dque的队尾为NULL)  队尾出队;
整型变量n获取队列大小
if(n == 0) break;//队列为空
将n和ans的最大值赋给ans
for(int i = 0; i < n; ++i)
{
队头赋值给tmp
队头出队
tmp的左右结点进队
}
}
return ans;
}


## 2.2 二叉树的堂兄弟节点

void dfs(TreeNode* root, TreeNode* p, int d, int x, int& depth, TreeNode** parent)
{
if (root == NULL) return;
if (root->val == x)
{
*parent = p;
depth = d;
return;
}
dfs(root->left, root, d + 1, x, depth, parent);
dfs(root->right, root, d + 1, x,  depth, parent);
}
bool isCousins(TreeNode* root, int x, int y)
{
int dx = 0;
int dy = 0;
TreeNode* px = NULL;
TreeNode* py = NULL;
dfs(root, NULL, 0, x, dx, &px);
dfs(root, NULL, 0, y, dy, &py);
return (dx == dy) && (px != py);
}


### 2.2.2 伪代码

void dfs(TreeNode* root, TreeNode* p, int d, int x, int& depth, TreeNode** parent)
{
获得深度及父节点;
}
bool isCousins(TreeNode* root, int x, int y)
{
定义dx,dy记录深度
定义px，py来记录父节点
找x;
找y;
深度相同，父节点不相同，则是二叉树的堂兄弟节点
}


### 2.2.4该题目解题优势及难点

posted @ 2020-04-12 22:04  极仙  阅读(248)  评论(0编辑  收藏  举报