相关知识——树
算法与数据结构实验题 6.1 橙子树
★实验任务
从前有一棵修炼成仙的橙子树,树上结满了神奇的橙子,只要吃了一枚就能 +1s。为了防止有刁民来偷吃橙子,树神就想召唤一名护法把橙子树上的所有橙 子都吃了,这样就没有人能偷走橙子啦。 橙子树上有 n 枚橙子,编号为 1~n,由 n-1 条树枝全部连起来,任意两个橙 子之间有且只有一条路径(由树枝组成的路径)相连,最开始时树神会选择其中 一枚橙子位置的编号 s 召唤一名护法并从这个位置开始吃,并且护法只能沿着树 枝移动,由于每条树枝的长度不同,而护法移动距离之和等于树神消耗的法力值, 树神想知道,让护法吃掉所有橙子所消耗的法力值最低为多少。 护法不需要回到最开始召唤他的位置(只需吃掉所有的橙子)。 ★数据输入 输入第一行为两个正整数 n 和 s,n 表示橙子的数量,s 表示召唤护法的起始 位置编号。 接下来 n-1 行,每行三个整数 u,v,w(w<=1000),表示编号为 u 和 v 的橙 子之间由一条长度为 w 的树枝直接相连。 30%的数据:n<=500; 60%的数据:n<=1000; 100%的数据:n<=100000。 ★数据输出
输出吃掉所有橙子所消耗的最低法力值(即移动距离之和的最小值)。
输入示例
5 2
1 2 1
2 3 2
3 4 2
4 5 1
输出示例
7
- 一脸懵逼,不会做
算法与数据结构实验题 6.25 地鼠安家 1
★实验任务
fd 是一个公认的美丽校园。一天,fd 来了一群地鼠,编号为 1 到 n,他们希望 在这里定居。现在先由第一只地鼠往下打一个单位的距离,并且在那里安家。对 于每一个已经安家的地鼠,如果他左下或右下没有邻居,那还没安家的地鼠就可 以在他的左下或者右下安家。地鼠们已经建完所有的窝了,他们评价这些窝合格 的标准是它们能不能形成一棵二叉搜索树。现在需要你帮助他们评估一下他们的 窝挖的是否合格。
★数据输入
第 1 行一个整数 n,表示地鼠总共 n 只。接下来一共 n 行,每一行三个数:l,o,r,其中 l 表示编号为 o 的地鼠的左邻居的编号,r 表示的是编号为 o 的右邻居的编号,如果没有左 邻居或右邻居,则 l 或 r 为-1。1<=n<=10000。
★数据输出
输出一行,如果如果他们的窝合格,则输出安居在最深的窝的地鼠离地面的距离,如果不合格,则输出-1。
输入示例
5
-1 1 -1
1 2 3
-1 3 -1
2 4 5
-1 5 -1
输出示例
3
#include<iostream>
using namespace std;
#define Max 10001
typedef struct btnode* btlink;
typedef struct btnode //定义树节点
{
int element;
btlink left;
btlink right;
int l, r;
};
btlink Newnode() //创建新节点
{
btlink node = new btnode;
node->left = node->right = NULL;
node->element = 0;
return node;
}
bool flag = false;//判断是否符合搜索树
void Inorder(btlink t)//判断函数,采用中序遍历的方法。首先判断左子树与其父节点是否满足对应关系,在判断右子树与其父节点是否满足搜索树对应的关系。采用递归实现
{
if (t != NULL && !flag)
{
Inorder(t->left);
if (t->left && (t->element < t->left->element))
{
flag = true;
}
if (t->right && (t->element > t->right->element))
{
flag = true;
}
Inorder(t->right);
}
return;
}
int getHeight(btlink t)//求深度
{
if (t == NULL)
{
return 0;
}
int lHight = getHeight(t->left);
int rHight = getHeight(t->right);
return (lHight > rHight ? (lHight + 1) : (rHight + 1));
}
int check[Max] = { 0 };//这个数组 只存在0 1 两种值 当过儿子就为0, 最后遍历一遍 没当过儿子的就是祖先
btlink a[Max]; //这个数组 存放的是指针, 每个指针都指向一只老鼠序号和下标对应
int main()
{
int n, i, l, o, r;
btlink tmp;
cin >> n;
for (int i = 0; i < n; i++)
{
cin >> l >> o >> r;
tmp = Newnode();
tmp->element = o;
tmp->l = l;
tmp->r = r;
a[o] = tmp;
}
for (i = 1; i <= n; i++)
{
if (a[i]->l != -1)
{
check[a[i]->l] = 1;
a[i]->left = a[a[i]->l];
}
else
{
a[i]->left = NULL;
}
if (a[i]->r != -1)
{
check[a[i]->r] = 1;
a[i]->right = a[a[i]->r];
}
else
{
a[i]->right = NULL;
}
}
int root;
btlink Troot = Newnode();
for (i = 1; i <= n; i++)
{
if (check[i] == 0)
{
Troot = a[i];
break;
}
}
Inorder(Troot);
if (!flag)
{
cout << getHeight(Troot);
}
else
{
cout << -1;
}
}
算法与数据结构实验题 6.32 我不会 AVL
★实验任务
欢迎来到暴走数据结构,我是洪尼玛。今天,我们来玩 AVL树,怎么玩呢?很简单:给 你n个数字,你需要按顺序插入一棵AVL树中,然后输出每个数所在节点的深度(从1开始)。 因为我不会AVL树,所以希望聪明的你们来帮我完成这个任务
★数据输入
输入第一个数为n(n≤100000)表示数字的个数
接下来一行输入n个数,范围在 1 到 n 之间,每个数只出现一次
★数据输出
按输入的顺序依次输出每个数所在节点的深度
输入示例
6
1 2 3 4 5 6
输出示例
3 2 3 1 2 3
★提示
注意:输出行末不能有空格
对于50%的数据,1<=n<=100
对于100%的数据,1<=n<=100000
链表实现的方法,但是存在超时的情况
#include<iostream>
#include<cstdio>
#define ElementType int
using namespace std;
typedef struct AVLNode* Position;
typedef Position AVLTree; /* AVL树类型 */
struct AVLNode {
ElementType Data; /* 结点数据 */
AVLTree Left; /* 指向左子树 */
AVLTree Right; /* 指向右子树 */
int Height; /* 树高 */
};
int GetHeight(Position T);
int Max(int, int);
Position SingleRoateWithLeft(Position A)
{
Position B;
B = A->Left;
A->Left = B->Right;
B->Right = A;
A->Height = Max(GetHeight(A->Left), GetHeight(A->Right)) + 1;
B->Height = Max(GetHeight(B->Left), GetHeight(B->Right)) + 1;
return B;//new node
}
Position SingleRoateWithRight(Position A)
{
Position B;
B = A->Right;
A->Right = B->Left;
B->Left = A;
A->Height = Max(GetHeight(A->Left), GetHeight(A->Right)) + 1;
B->Height = Max(GetHeight(B->Left), GetHeight(B->Right)) + 1;
return B;
}
Position DoubleRoateWithLeft(Position A)
{
A->Left = SingleRoateWithRight(A->Left);
return SingleRoateWithLeft(A);
}
Position DoubleRoateWithRight(Position A)
{
A->Right = SingleRoateWithLeft(A->Right);
return SingleRoateWithRight(A);
}
AVLTree MakeEmpty(AVLTree T)
{
if (T != NULL)
{
MakeEmpty(T->Left);
MakeEmpty(T->Right);
free(T);
}
return NULL;
}
Position Find(ElementType X, AVLTree T)
{
if (T == NULL)
{
return NULL;
}
if (X < T->Data)
{
return Find(X, T->Left);
}
else if (X > T->Data)
{
return Find(X, T->Right);
}
else
{
return T;
}
}
Position FindMin(AVLTree T)
{
if (T == NULL)
{
return NULL;
}
else if (T->Left == NULL)
{
return T;
}
else
{
return FindMin(T->Left);
}
}
Position FindMax(AVLTree T)
{
if (T == NULL)
{
return NULL;
}
else if (T->Right == NULL)
{
return T;
}
else
{
return FindMax(T->Right);
}
}
AVLTree Insert(ElementType X, AVLTree T)
{
if (T == NULL)
{
T = new AVLNode;
T->Data = X;
T->Left = T->Right = NULL;
T->Height = 0;
}
else if (X < T->Data)
{
T->Left = Insert(X, T->Left);
if (GetHeight(T->Left) - GetHeight(T->Right) == 2)
{
if (X < T->Left->Data)
{
T = SingleRoateWithLeft(T);
}
else
{
T = DoubleRoateWithLeft(T);
}
}
}
else
{
T->Right = Insert(X, T->Right);
if (GetHeight(T->Right) - GetHeight(T->Left) == 2)
{
if (X > T->Right->Data)
{
T = SingleRoateWithRight(T);
}
else
{
T = DoubleRoateWithRight(T);
}
}
}
T->Height = Max(GetHeight(T->Left), GetHeight(T->Right)) + 1;
return T;
}
AVLTree BuildNewTree(ElementType X)
{
AVLNode* T = new AVLNode;
T->Data = X;
T->Height = 0;
T->Right = T->Left = NULL;
return T;
}
int Max(int a, int b)
{
return a > b ? a : b;
}
int GetHeight(Position T)
{
int hr, hl;
if (!T)
{
return 0;
}
hl = GetHeight(T->Left);
hr = GetHeight(T->Right);
return (hl > hr) ? ++hl : ++hr;
}
void showHeight(int a, Position T)
{
if (T == NULL)
{
return;
}
showHeight(a, T->Left);
cout << T->Height << ' ';
showHeight(a, T->Right);
}
void showdeep(int depth, Position T,int a[])
{
if (T == NULL) return;
if (T)
{
showdeep(depth + 1, T->Left,a);
a[T->Data] = depth + 1;
showdeep(depth + 1, T->Right,a);
}
}
int main()
{
int n;
cin >> n;
int m;
AVLTree T = NULL;
int *b = new int[n];
for (int i = 0; i < n; i++)
{
scanf_s("%d", &m);
b[i] = m;
T = Insert(m, T);
}
//showHeight(GetHeight(T)+1,T);
int* a = new int[n+1];
showdeep(0, T,a);
for (int i = 0; i < n; i++)
{
if (i < n-1 ) printf_s("%d ", a[b[i]]);
else printf_s("%d", a[b[i]]) ;
}
}
数组实现的方法(未测试)
#include<iostream>
#include<cstdlib>
using namespace std;
typedef struct AVLNode* Position;
typedef Position AvlTree;
struct AVLNode
{
int data;
int left, right;
int height;
};
AVLNode* TreeArr = NULL;
int GetHeight(int T)
{
return TreeArr[T].height;
}
int max(int a, int b)
{
return a > b ? a : b;
}
int Single_R(int A)
{
int B;
B = TreeArr[A].right;
TreeArr[A].right = TreeArr[B].left;
TreeArr[B].left = A;
TreeArr[A].height = max(GetHeight(TreeArr[A].left), GetHeight(TreeArr[A].right)) + 1;
TreeArr[B].height = max(GetHeight(TreeArr[B].left), GetHeight(TreeArr[B].right)) + 1;
return B;
}
int Single_L(int A)
{
int B;
B = TreeArr[A].left;
TreeArr[A].left = TreeArr[B].right;
TreeArr[B].right = A;
TreeArr[A].height = max(GetHeight(TreeArr[A].left), GetHeight(TreeArr[A].right)) + 1;
TreeArr[B].height = max(GetHeight(TreeArr[B].left), GetHeight(TreeArr[B].right)) + 1;
return B;
}
int Double_R(int A)
{
TreeArr[A].left = Single_R(TreeArr[A].left);
return Single_L(A);
}
int Double_L(int A)
{
TreeArr[A].right = Single_L(TreeArr[A].right);
return Single_R(A);
}
int Insert(int data, int T)
{
if (T == 0)
{
TreeArr[data].data = data;
TreeArr[data].height = 1;
return data;
}
else if(data<TreeArr[T].data)
{
TreeArr[T].left = Insert(data,TreeArr[T].left);
if (GetHeight(TreeArr[T].left) - GetHeight(TreeArr[T].right) == 2)
{
if (data < TreeArr[TreeArr[T].left].data)
{
T = Single_L(T);
}
else
{
T = Double_L(T);
}
}
}
else if(data>TreeArr[T].data)
{
TreeArr[T].right = Insert(data, TreeArr[T].right);
if (GetHeight(TreeArr[T].right) -GetHeight( TreeArr[T].left) == 2)
{
if (data > TreeArr[TreeArr[T].right].data)
{
T = Single_R(T);
}
else
{
T = Double_R(T);
}
}
}
TreeArr[T].height = max(GetHeight(TreeArr[T].left), GetHeight(TreeArr[T].right))+1;
return T;
}
void dfs(int index, int step)
{
if (index == 0) return;
TreeArr[index].height = step;
dfs(TreeArr[index].left, step + 1);
dfs(TreeArr[index].right, step + 1);
}
int main()
{
int n;
cin >> n;
int* data = new int[n];
TreeArr = new AVLNode[n + 1];
memset(TreeArr, 0, sizeof(AVLNode) * (n + 1));
int root = 0;
for (int i = 0; i < n; i++)
{
cin >> data[i];
root = Insert(data[i], root);
}
dfs(root, 1);
for (int i = 0; i < n; i++)
{
if (!i)
{
cout << TreeArr[data[i]].height;
}
else
{
cout << ' ' << TreeArr[data[i]].height;
}
}
}