算法与数据结构第六、七次作业——树

相关知识——
算法与数据结构实验题 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;
		 }
	 }
 }
原文地址:https://www.cnblogs.com/wangmou-233-1024-com/p/13855445.html