数据结构--二叉树作业

1.第1关: 基于二叉链表的二叉树左右孩子的交换 

#include<iostream>
#include<cstring>
using namespace std;
typedef struct BiTNode
{
	char data;
	struct BiTNode *lchild,*rchild;
}BiTNode,*BiTree;
void CreateBiTree(BiTree &T,char S[],int &i)
{//先序建立二叉树
	if(S[i]=='0')
		T=NULL;
	else
	{
		T=new BiTNode;
		T->data=S[i];
		CreateBiTree(T->lchild,S,++i);
		CreateBiTree(T->rchild,S,++i);
	}
}
void ChangeRL(BiTree &T)
{//二叉树左右孩子的交换
/**************begin************/
	if (T == NULL)
		return;

	BiTNode* p = T->lchild;
	T->lchild = T->rchild;
	T->rchild = p;

	ChangeRL(T->lchild);  // 递归处理左子树
	ChangeRL(T->rchild);  // 递归处理右子树




    
    /**************end************/
}
void PreOrderTraverse(BiTree T)
{//先序遍历
	if(T)
	{
    	cout<<T->data;
		PreOrderTraverse(T->lchild);
		PreOrderTraverse(T->rchild);
	}
}
int main()
{
	char S[100];
	while(cin>>S)
    {
        if(strcmp(S,"0")==0) break;
		int i=-1;
	  	BiTree T;
		CreateBiTree(T,S,++i);
		ChangeRL(T);
		PreOrderTraverse(T);
		cout<<endl;
	}
	return 0;
}

2.第2关: 基于二叉链表的二叉树的双序遍历

#include<iostream>
#include <string.h>
using namespace std;
typedef struct BiTNode
{
	char data;
	struct BiTNode *lchild,*rchild;
}BiTNode,*BiTree;
void CreateBiTree(BiTree &T,char S[],int &i)
{//先序建立二叉树
	if(S[i]=='0')
		T=NULL;
	else
	{
		T=new BiTNode;
		T->data=S[i];
		CreateBiTree(T->lchild,S,++i);
		CreateBiTree(T->rchild,S,++i);
	}
}
void DoubleTraverse(BiTree T)
{//双序遍历二叉树T的递归算法
/**************begin************/

    if (T == NULL)
		return;
	else
	{
		cout << T->data;
		DoubleTraverse(T->lchild);
		cout << T->data;
		DoubleTraverse(T->rchild);
	}



    /**************end************/
}
int main()
{
	char S[100];
	while(cin>>S)
    {
        if(strcmp(S,"0")==0) break;
        int i=-1;
	  	BiTree T;
		CreateBiTree(T,S,++i);
		DoubleTraverse(T);
		cout<<endl;
	}
	return 0;
}

3.第3关: 基于二叉链表的二叉树最大宽度的计算

利用队列进行层次遍历
#include <iostream>
#include <string.h>
#include<queue>
using namespace std;

typedef struct BiTNode
{
    char data;
    struct BiTNode *lchild,*rchild;
}BiTNode,*BiTree;

BiTree CreateBiTree(int &pos, char *str)
{// 先序建立二叉树
    char c=str[pos++];
    if(c=='0') return NULL;
    BiTree root=new BiTNode();
    root->data=c;
    root->lchild=CreateBiTree(pos,str);
    root->rchild=CreateBiTree(pos,str);
    return root;
}

int Width(BiTree T)
{// 求二叉树T最大宽度
/**************begin************/

    if (!T)
        return 0;

    int maxWidth = 0;
    queue<BiTree> q;

    q.push(T);

    while (!q.empty())
    {
        int nowWidth = q.size(); 
        for (int i = 0; i < nowWidth; ++i)
        {
            BiTree node = q.front();
            q.pop();

            if (node->lchild)
                q.push(node->lchild);
            if (node->rchild)
                q.push(node->rchild);
        }

        // 更新最大宽度
        maxWidth = max(maxWidth, nowWidth);
    }

    return maxWidth;



    /**************end************/
}

int main()
{
    char str[1000];
    while(cin>>str)
    {
        if(strcmp(str,"0")==0) break;
        int pos=0;                         // 标记字符串处理位置
        BiTree root=CreateBiTree(pos,str);
        cout<<Width(root)<<endl;
    }
    return 0;
}

4.第4关:基于二叉链表的二叉树最长路径

#include<iostream>
#include<vector>
#include<queue>
#define MAXSIZE 100
using namespace std;
typedef struct BiTNode
{
	char data;
	struct BiTNode* lchild, * rchild;
}BiTNode, * BiTree;
void CreateBiTree(BiTree& T, char S[], int& i)
{//程序生成器
	if (S[i] == '0')
		T = NULL;
	else
	{
		T = new BiTNode;
		T->data = S[i];
		CreateBiTree(T->lchild, S, ++i);
		CreateBiTree(T->rchild, S, ++i);
	}
}


void LongestPath(BiTree T)
{//双击以监控参考的最大数量B
/**************begin************/
	if (T == NULL)
	{
		return;
	}

	vector<char> currentPath;
	vector<char> longestPath;

	queue<pair<BiTree, vector<char>>> q;
	q.push({ T, {T->data} });

	while (!q.empty())
	{
		auto current = q.front();
		q.pop();

		BiTree node = current.first;
		vector<char> currentPath = current.second;

		if (node->lchild == nullptr && node->rchild == nullptr)
		{
			if (currentPath.size() > longestPath.size())
			{
				longestPath = currentPath;
			}
		}

		if (node->lchild != nullptr)
		{
			vector<char> newPath = currentPath;
			newPath.push_back(node->lchild->data);
			q.push({ node->lchild, newPath });
		}

		if (node->rchild != nullptr)
		{
			vector<char> newPath = currentPath;
			newPath.push_back(node->rchild->data);
			q.push({ node->rchild, newPath });
		}
	}
	cout << longestPath.size() << endl;
	for (char node : longestPath)
	{
		cout << node;
	}
	cout << endl;

	/**************end************/
}
int main()
{
	char S[100];
	while (cin >> S && S[0] != '0')
	{
		int i = -1;
		BiTree T;
		CreateBiTree(T, S, ++i);
		LongestPath(T);
	}
	return 0;
}

5.第5关: 基于二叉链表的二叉树叶子结点到根结点的路径的求解

#include<iostream>
using namespace std;
char path[100];  //路径数组,存储路径上每个结点的值
typedef struct BiTNode
{
	char data;
	struct BiTNode *lchild,*rchild;
}BiTNode,*BiTree;
void CreateBiTree(BiTree &T,char S[],int &i)
{//先序建立二叉树
	if(S[i]=='0')
		T=NULL;
	else
	{
		T=new BiTNode;
		T->data=S[i];
		CreateBiTree(T->lchild,S,++i);
		CreateBiTree(T->rchild,S,++i);
	}
}
void AllPath(BiTree T,char path[],int pathlen)
{//二叉树叶子结点到根结点的路径的求解
/**************begin************/
    
if (T != NULL)
	{
		path[pathlen] = T->data;
		AllPath(T->lchild, path, pathlen + 1);
		AllPath(T->rchild, path, pathlen + 1);
		if (T->lchild == NULL && T->rchild == NULL) // 如果是叶子结点,输出路径并清空路径
		{
			for (int i = pathlen; i >= 0; i--)
				cout << path[i];
			cout << endl;
		}
	}
	return;



    
    /**************end************/
}
int main()
{
	char S[100];
	while(cin>>S&&S[0]!='0')
	{
		int i=-1;
		BiTree T;
		CreateBiTree(T,S,++i);
		int pathlen=0;         //初始化路径到根结点的长度为0
        AllPath(T,path,pathlen);
	}
	return 0;
}

6.第6关: 基于二叉树的表达式求值

ps:其中的二叉树的创建很特别,值得二次看
#include<iostream>
#define MAXSIZE 100
using namespace std;


typedef struct BiTNode
{//二叉树的双链表存储表示
	double data;          //结点数据域
	bool ischaracter;      //判断结点是否为字符
	struct BiTNode* lchild, * rchild;    //左右孩子指针
}BiTNode, * BiTree;


typedef struct
{//字符栈的存储结构
	char* base;     //栈底指针
	char* top;       //栈顶指针
	int stacksize;   //栈可用的最大容量
}SqStack1;


typedef struct
{//结点栈的存储结构
	BiTree* base;
	BiTree* top;
	int stacksize;
}SqStack2;


void InitStack1(SqStack1& s)
{//字符栈的初始化
	s.base = new char[MAXSIZE];  //为顺序栈动态分配一个最大容量为MAXSIZE的数组空间
	s.top = s.base;              //初始为空栈
	s.stacksize = MAXSIZE;        //置栈的最大容量为MAXSIZE
}


void InitStack2(SqStack2& s)
{//结点栈的初始化
	s.base = new BiTree[MAXSIZE];
	s.top = s.base;
	s.stacksize = MAXSIZE;
}


void Push1(SqStack1& s, char ch)
{//字符入栈操作
	if (s.top - s.base == s.stacksize)   //栈满
		return;
	*s.top = ch;    //元素ch压入栈顶
	s.top++;       //栈顶指针加1
}


void Push2(SqStack2& s, BiTree t)
{//结点入栈操作
	if (s.top - s.base == s.stacksize)
		return;
	*s.top = t;
	s.top++;
}


void Pop1(SqStack1& s, char& ch)
{//字符出栈操作
	if (s.top == s.base)     //栈空
		return;
	else
	{
		s.top--;     //栈顶指针减1
		ch = *s.top;   //将栈顶元素赋给ch
	}
}


void Pop2(SqStack2& s, BiTree& t)
{//结点出栈操作
	if (s.top == s.base)
		return;
	else
	{
		s.top--;
		t = *s.top;
	}
}


char GetTop(SqStack1 s)
{//取字符栈的栈顶元素
	if (s.base == s.top)    //栈空
		return -1;
	else
		return *(s.top - 1);    //返回栈顶元素的值,栈顶指针不变
}


bool EmptyStack(SqStack1 s)
{//栈的判空操作
	if (s.base == s.top)   //栈空返回true
		return true;
	else
		return false;   //栈非空返回false
}


char Precede(char a, char b)
{//判断符号的优先级
	if (a == '+' || a == '-')
	{
		if (b == '+' || b == '-' || b == ')' || b == '=')
			return '>';    //>代表a的优先级高于b
		else
			return '<';
	}
	else if (a == '*' || a == '/')
	{
		if (b == '+' || b == '-' || b == '*' || b == '/' || b == ')' || b == '=')
			return '>';
		else
			return '<';
	}
	else if (a == '(')
	{
		if (b == ')')
			return '=';
		else
			return '<';
	}
	else if (a == ')')
		return '>';
	else
	{
		if (b == '=')
			return '=';
		else
			return '<';
	}
}


double Operate(double a, char ch, double b)
{//运算操作,返回相应的数值结果
	if (ch == '+')
		return a + b;
	else if (ch == '-')
		return a - b;
	else if (ch == '*')
		return a * b;
	else
		return a / b;
}


bool IsCharacter(char ch)
{//判断ch是否为+、-、*、/、(、)、= 这类的字符,是则返回true
	if (ch == '+' || ch == '-' || ch == '*' || ch == '/' || ch == '(' || ch == ')' || ch == '=')
		return true;
	else
		return false;
}


double InOrder(BiTree T)
{//中序遍历二叉树并求表达式的值
/**************begin************/
	if (T != NULL)
	{
		if (T->ischaracter)
		{
			double left = InOrder(T->lchild);
			double right = InOrder(T->rchild);
			return Operate(left, T->data, right);
		}
		else
		{
			return T->data;
		}
	}

	return 0.0;

		/**************end************/
}


void CreateBT(char ch[], BiTree& t, SqStack1 optr, SqStack2 expt)
{//创建二叉树

	int i = 0;
	char opr, c[2];  //辅助数组c
	BiTree t1, t2;
	double num;
	while (ch[i] != '\0' || !EmptyStack(optr))
	{
		if (!IsCharacter(ch[i]))     //当前遍历的不是运算符元素
		{
			c[0] = ch[i];
			c[1] = '\0';
			BiTree q = new BiTNode;     //生成一个新结点*q
			num = strtod(c, NULL);      //将字符数组c转换成浮点数,赋给num
			q->ischaracter = false;   //结点*q不为运算符
			q->data = num;            //结点数据域置为num
			q->lchild = NULL;         //左右孩子置为NULL
			q->rchild = NULL;
			Push2(expt, q);       //将结点q压入数字栈
			i++;                  //指针i加1
		}//if
		else                 //当前遍历的是运算符元素
		{
			switch (Precede(GetTop(optr), ch[i]))    //比较栈顶元素和当前遍历字符的优先级
			{
			case '<':                //栈顶元素优先级小于当前运算符
				Push1(optr, ch[i]);     //将当前运算符入栈
				i++;                  //指针i加1
				break;
			case '>':              //栈顶元素优先级大于当前运算符
				Pop1(optr, opr);     //运算符栈的元素出栈
				Pop2(expt, t2);      //数字栈的栈顶元素出栈
				Pop2(expt, t1);
				t = new BiTNode;      //生成新结点*t
				t->ischaracter = true;     //结点*t为运算符
				t->data = opr;          //结点数据域置为opr
				t->lchild = t1;        //左孩子指向t1
				t->rchild = t2;        //右孩子指向t2
				Push2(expt, t);       //将结点t压入数字栈
				break;
			case '=':         //栈顶元素优先级等于当前运算符
				Pop1(optr, opr);    //运算符栈的元素出栈
				i++;                //指针i加1
				break;
			}//switch
		}//else
	}//while
}


int main()
{
	char ch[MAXSIZE];
	while (cin >> ch)
	{
		if (ch[0] == '=') break;
		BiTree t;
		SqStack1 optr;      //运算符栈optr
		SqStack2 expt;        //数字栈expt

		InitStack1(optr);     //初始化栈
		InitStack2(expt);     //初始化栈

		Push1(optr, '=');    //先在运算符栈底放入一个'='
		CreateBT(ch, t, optr, expt);       //创建二叉树

		double answer = InOrder(t);
		cout << answer << endl;
	}
	return 0;
}

7.第7关: 二叉树的WPL计算

#include<iostream>
using namespace std;
typedef struct BiTNode
{
	int weight;
	struct BiTNode *left,*right;
}BiTNode,*BiTree;
void CreateBiTree(BiTree &T)
{//先序建立二叉树
	int x;
	cin>>x;
	if(x==0) T=NULL;
	else
    {
		T=new BiTNode;
		T->weight=x;
		CreateBiTree(T->left);
		CreateBiTree(T->right);
	}
}
int WPL(BiTree &T,int d)
{//求二叉树T的带权路径长度
/**************begin************/
   


if (!T) {
		return 0;
	}
	else if (T->left==NULL && T->right==NULL) {
		return d * T->weight;
	}
	else {
		return WPL(T->left, d + 1) + WPL(T->right, d + 1);
	}
    /**************end************/
}
int main()
{
	while(1)
    {
		BiTree T;
		CreateBiTree(T);
		if(!T) break;
		int d=0;          //调用时T指向二叉树的根结点,d为0
		cout<<WPL(T,d)<<endl;
	}
	return 0;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值