[数据结构]二叉树的实现及应用

要求

编写程序,实现二叉树类及若干应用算法。
要求采用二叉链表结构,实现以下功能:
1)构造函数:根据带空指针标记的先序遍历序列构造对象;根据先序和中序遍历序列构造对象;

2)析构函数:释放所有结点空间;
3)先序、中序、后序、层次遍历算法;
4)统计叶子结点、单分支结点、双分支结点的个数;
5)计算二叉树的高度;

(6)根据关键值查找结点;

(7)查找某个结点的父结点。

以下图二叉树为例:

带空指针的形式abd**e**cf***: 

1.先序遍历:abdecf(根->左子树->右子树)

中序遍历:dbeafc(左子树->根->右子树)

后序遍历:debfca(左子树->右子树->根)

层次遍历:abcdef(逐层遍历,从左到右依次访问每个节点)

2.叶子结点、单分支结点、双分支结点的个数分别为:312

3.高度:3

.h代码拆解

构造函数

(1)带空指针的先序序列

private:
template<class T>
BiNode<T>* BiTree<T>::CreateByPreNull(vector<T>& pre, int& i)
{
	T e = pre[i];
	i++;
	if (e == '*') return NULL;
	BiNode<T>* p = new BiNode<T>(e);
	p->lchild = CreateByPreNull(pre, i);
	p->rchild = CreateByPreNull(pre, i);

	return p;
}
public:
BiTree(vector<T>& pre)			// 由先序序列构造二叉树
{
	int i = 0;
	root = CreateByPreNull(pre, i);
}

(2)先序和中序

private:
template<class T>
BiNode<T>* BiTree<T>::CreateByPreMid(vector<T>& pre, vector<T>& mid, int ipre, int imid, int n)
{
	if (n == 0)
		return NULL;
	BiNode<T>* p = new BiNode<T>;
	p->data = pre[ipre];
	int i = 0;
	for (; i < n; i++) {
		if (pre[ipre] == mid[imid + i])
			break;
	}
	p->lchild = CreateByPreMid(pre, mid, ipre + 1, imid, i);
	p->rchild = CreateByPreMid(pre, mid, ipre + i + 1, imid + i + 1, n - i - 1);

	return p;
}
public:
template<class T>
inline BiTree<T>::BiTree(vector<T>& pre, vector<T>& mid)
{
	int n = pre.size();
	root = CreateByPreMid(pre, mid, 0, 0, n);
}

析构函数

public:
    ~BiTree() { Destory(root); }
private:
    template<class T>
    void BiTree<T>::Destory(BiNode<T>* p)
    {
	    if (p == NULL)	return;
	    Destory(p->lchild);
	    Destory(p->rchild);
	    delete p;
    }

遍历:先序、中序、后续、层次

public:
	void PreOrder() { PreOrder(root); }
	void InOrder() { InOrder(root); }
	void PostOrder() { PostOrder(root); }
	void LevelOrder() {
		if (root == NULL)	return;
		LinkQueue<BiNode<T>*> Q;
		Q.EnQueue(root);
		while (!Q.Empty()){
			auto p = Q.DeQueue();
			cout << p->data << " ";
			if (p->lchild != NULL)	Q.EnQueue(p->lchild);
			if (p->rchild != NULL)	Q.EnQueue(p->rchild);
		}
	}
private:
void PreOrder(BiNode<T>* p);
void InOrder(BiNode<T>* p);
void PostOrder(BiNode<T>* p);

template<class T>
void BiTree<T>::PreOrder(BiNode<T>* p)
{
	if (p == NULL)	return;
	cout << p->data << " ";
	PreOrder(p->lchild);
	PreOrder(p->rchild);
}

template<class T>
void BiTree<T>::InOrder(BiNode<T>* p)
{
	if (p == NULL)	return;
	InOrder(p->lchild);
	cout << p->data << " ";
	InOrder(p->rchild);
}

template<class T>
void BiTree<T>::PostOrder(BiNode<T>* p)
{
	if (p == NULL)	return;
	PostOrder(p->lchild);
	PostOrder(p->rchild);
	cout << p->data << " ";
}

统计叶子结点、单分支结点、双分支结点的个数

public:
int leafNodeCount() { return leafNodeCount(root); }
int singleNodeCount() { return singleNodeCount(root); }
int doubleNodeCount() { return doubleNodeCount(root); }

private:
template<class T>
inline int BiTree<T>::leafNodeCount(BiNode<T>* p)
{
	if (!p) return 0;
	if (p->lchild == NULL && p->rchild == NULL) return 1;
	int left = leafNodeCount(p->lchild);
	int right = leafNodeCount(p->rchild);
	return left + right;
}
template<class T>
inline int BiTree<T>::singleNodeCount(BiNode<T>* p)
{
	if (!p) return 0;
	int res = 0;
	if ((p->lchild == NULL && p->rchild) || (p->lchild && p->rchild == NULL)) res++;
	int left = singleNodeCount(p->lchild);
	int right = singleNodeCount(p->rchild);
	return left + right + res;
}
template<class T>
inline int BiTree<T>::doubleNodeCount(BiNode<T>* p)
{
	if (!p) return 0;
	int res = 0;
	if (p->lchild && p->rchild) res++;
	int left = doubleNodeCount(p->lchild);
	int right = doubleNodeCount(p->rchild);
	return res + left + right;
}

高度

public:
int Height() { return Height(root); }	

private:
template<class T>
int BiTree<T>::Height(BiNode<T>* p)
{
	if (p == NULL)	return 0;
	int left = Height(p->lchild);
	int right = Height(p->rchild);
	return max(left, right) + 1;     // #include <algorithm>
}

查找结点

private:
template<class T>
BiNode<T>* BiTree<T>::Search(BiNode<T>* p, T e){
	if (p == NULL)	return NULL;
	if (p->data == e) return p;
	BiNode<T>* q = Search(p->lchild, e);
	if (q != NULL)	return q;
	return Search(p->rchild, e);
}

public:
bool Search(T e) {
		BiNode<T>* q = Search(root, e);
		if (q == NULL)
		{
			cout << "未找到该结点" << endl;
			return false;
		}
		else
		{
			cout << "该结点为:" << q->data << endl;
			return true;
		}
	}

查找父结点

根据孩子结点的值查找

public:
bool SearchParent(T e)
	{
		BiNode<T>* q = SearchParent(root, e);
		if (q == NULL){
			cout << "该结点无父结点" << endl;
			return false;
		}
		else{
			cout << "该结点的父结点为:" << q->data << endl;
			return true;
		}
	}

private:
template<class T>
BiNode<T>* BiTree<T>::SearchParent(BiNode<T>* p, T e){
	if (p == NULL)	return NULL;
	if (p->lchild && p->lchild->data == e)	return p;
	if (p->rchild && p->rchild->data == e)	return p;
	BiNode<T>* q = SearchParent(p->lchild, e);
	if (q != NULL) return q;
	return SearchParent(p->rchild, e);
}

根据孩子结点的指针查找

private:
template<class T>
BiNode<T>* BiTree<T>::SearchParent(BiNode<T>* p, BiNode<T>* child){
	if (p == NULL || child == NULL)	return NULL;
	if (p->lchild == child || p->rchild == child)	return p;
	BiNode<T>* q = SearchParent(p->lchild, child);
	if (q != NULL) return q;
	return SearchParent(p->rchild, child);
}
public:
BiNode<T>* SearchParent(BiNode<T>* child) { return SearchParent(root, child); }

.h全部代码

#pragma once
#include <vector>
#include "LinkQueue.h"
#include <algorithm>

template <class T>
struct BiNode
{
	T data;
	BiNode<T>* lchild;
	BiNode<T>* rchild;
	BiNode() :lchild(NULL), rchild(NULL) {}
	BiNode(const T& x) :data(x), lchild(NULL), rchild(NULL) {}
};

template <class T>
class BiTree
{
private:
	BiNode<T>* root;
	void PreOrder(BiNode<T>* p);
	void InOrder(BiNode<T>* p);
	void PostOrder(BiNode<T>* p);
	BiNode<T>* CreateByPreNull(vector<T>&, int&);
	BiNode<T>* CreateByPreMid(vector<T>&, vector<T>&, int, int, int);
	void Destory(BiNode<T>* p);
	int Count(BiNode<T>* p);
	int leafNodeCount(BiNode<T>* p);
	int singleNodeCount(BiNode<T>* p);
	int doubleNodeCount(BiNode<T>* p);
	int Height(BiNode<T>* p);
	BiNode<T>* Search(BiNode<T>* p, T e);
	BiNode<T>* SearchParent(BiNode<T>* p, BiNode<T>* child);
	BiNode<T>* SearchParent(BiNode<T>* p, T e);
public:
	BiTree() { root = NULL; }
	BiTree(vector<T>& pre)			// 由先序序列构造二叉树
	{
		int i = 0;
		root = CreateByPreNull(pre, i);
	}
	BiTree(vector<T>& pre, vector<T>& mid);
	BiTree(BiTree<T>& tree);
	~BiTree() { Destory(root); }
	void PreOrder() { PreOrder(root); }
	void InOrder() { InOrder(root); }
	void PostOrder() { PostOrder(root); }
	void LevelOrder() {
		if (root == NULL)	return;

		LinkQueue<BiNode<T>*> Q;
		Q.EnQueue(root);

		while (!Q.Empty())
		{
			auto p = Q.DeQueue();
			cout << p->data << " ";

			if (p->lchild != NULL)	Q.EnQueue(p->lchild);
			if (p->rchild != NULL)	Q.EnQueue(p->rchild);
		}
	}
	int Count() { return Count(root); }					// 统计节点个数
	int leafNodeCount() { return leafNodeCount(root); }
	int singleNodeCount() { return singleNodeCount(root); }
	int doubleNodeCount() { return doubleNodeCount(root); }
	int Height() { return Height(root); }					// 计算二叉树的高度
	bool Search(T e) {
		BiNode<T>* q = Search(root, e);
		if (q == NULL)
		{
			cout << "未找到该结点" << endl;
			return false;
		}
		else
		{
			cout << "该结点为:" << q->data << endl;
			return true;
		}
	}
	BiNode<T>* SearchParent(BiNode<T>* child) { return SearchParent(root, child); }
	bool SearchParent(T e)
	{
		BiNode<T>* q = SearchParent(root, e);
		if (q == NULL)
		{
			cout << "该结点无父结点" << endl;
			return false;
		}
		else
		{
			cout << "该结点的父结点为:" << q->data << endl;
			return true;
		}
	}
};



template<class T>
void BiTree<T>::PreOrder(BiNode<T>* p)
{
	if (p == NULL)	return;
	cout << p->data << " ";
	PreOrder(p->lchild);
	PreOrder(p->rchild);
}

template<class T>
void BiTree<T>::InOrder(BiNode<T>* p)
{
	if (p == NULL)	return;
	InOrder(p->lchild);
	cout << p->data << " ";
	InOrder(p->rchild);
}

template<class T>
void BiTree<T>::PostOrder(BiNode<T>* p)
{
	if (p == NULL)	return;
	PostOrder(p->lchild);
	PostOrder(p->rchild);
	cout << p->data << " ";
}

template<class T>
BiNode<T>* BiTree<T>::CreateByPreNull(vector<T>& pre, int& i)
{
	T e = pre[i];
	i++;
	if (e == '*') return NULL;
	BiNode<T>* p = new BiNode<T>(e);
	p->lchild = CreateByPreNull(pre, i);
	p->rchild = CreateByPreNull(pre, i);

	return p;
}
template<class T>
BiNode<T>* BiTree<T>::CreateByPreMid(vector<T>& pre, vector<T>& mid, int ipre, int imid, int n)
{
	if (n == 0)
		return NULL;
	BiNode<T>* p = new BiNode<T>;
	p->data = pre[ipre];
	int i = 0;
	for (; i < n; i++) {
		if (pre[ipre] == mid[imid + i])
			break;
	}
	p->lchild = CreateByPreMid(pre, mid, ipre + 1, imid, i);
	p->rchild = CreateByPreMid(pre, mid, ipre + i + 1, imid + i + 1, n - i - 1);

	return p;
}
template<class T>
inline BiTree<T>::BiTree(vector<T>& pre, vector<T>& mid)
{
	int n = pre.size();
	root = CreateByPreMid(pre, mid, 0, 0, n);
}


template<class T>
void BiTree<T>::Destory(BiNode<T>* p)
{
	if (p == NULL)	return;
	Destory(p->lchild);
	Destory(p->rchild);
	delete p;
}

template<class T>
int BiTree<T>::Count(BiNode<T>* p)
{
	if (p == NULL)	return 0;

	int left = Count(p->lchild);
	int right = Count(p->rchild);

	return left + right + 1;
}

template<class T>
inline int BiTree<T>::leafNodeCount(BiNode<T>* p)
{
	if (!p) return 0;
	if (p->lchild == NULL && p->rchild == NULL) return 1;
	int left = leafNodeCount(p->lchild);
	int right = leafNodeCount(p->rchild);
	return left + right;
}

template<class T>
inline int BiTree<T>::singleNodeCount(BiNode<T>* p)
{
	if (!p) return 0;
	int res = 0;
	if ((p->lchild == NULL && p->rchild) || (p->lchild && p->rchild == NULL)) res++;
	int left = singleNodeCount(p->lchild);
	int right = singleNodeCount(p->rchild);
	return left + right + res;
}

template<class T>
inline int BiTree<T>::doubleNodeCount(BiNode<T>* p)
{
	if (!p) return 0;
	int res = 0;
	if (p->lchild && p->rchild) res++;
	int left = doubleNodeCount(p->lchild);
	int right = doubleNodeCount(p->rchild);
	return res + left + right;
}

template<class T>
int BiTree<T>::Height(BiNode<T>* p)
{
	if (p == NULL)	return 0;

	int left = Height(p->lchild);
	int right = Height(p->rchild);

	return max(left, right) + 1;
}

template<class T>
BiNode<T>* BiTree<T>::Search(BiNode<T>* p, T e)
{
	if (p == NULL)	return NULL;
	if (p->data == e) return p;

	BiNode<T>* q = Search(p->lchild, e);
	if (q != NULL)	return q;

	return Search(p->rchild, e);
}

template<class T>
BiNode<T>* BiTree<T>::SearchParent(BiNode<T>* p, BiNode<T>* child)
{
	if (p == NULL || child == NULL)	return NULL;

	if (p->lchild == child || p->rchild == child)	return p;

	BiNode<T>* q = SearchParent(p->lchild, child);
	if (q != NULL) return q;

	return SearchParent(p->rchild, child);
}

template<class T>
BiNode<T>* BiTree<T>::SearchParent(BiNode<T>* p, T e)
{
	if (p == NULL)	return NULL;

	if (p->lchild && p->lchild->data == e)	return p;
	if (p->rchild && p->rchild->data == e)	return p;

	BiNode<T>* q = SearchParent(p->lchild, e);
	if (q != NULL) return q;

	return SearchParent(p->rchild, e);
}

.cpp测试代码

#define _CRT_SECURE_NO_WARNINGS
#include "LinkQueue.h"
#include "BiTree.h"
#include <iostream>
#include <string>
using namespace std;//abd**e**cf***

void PrintMenu()
{
	cout << "---------------------------" << endl;
	cout << "请选择需要进行的操作" << endl;
	cout << "1. 用四种方法遍历二叉树" << endl;
	cout << "2. 计算结点总数、叶子结点总数、单分支结点数、双分支结点数和树高" << endl;
	cout << "3. 根据关键值查找结点" << endl;
	cout << "4. 求某个结点的父节点" << endl;
	cout << "5. 退出当前操作" << endl;
	cout << "---------------------------" << endl;
}

template <class T>
void operate(BiTree<T>& BT) {
	while (1)
	{
		bool flag = true;
		PrintMenu();
		int op;	cin >> op;
		switch (op) {
		case 1:
		{
			cout << "先序遍历结果:";
			BT.PreOrder();
			cout << endl;

			cout << "中序遍历结果:";
			BT.InOrder();
			cout << endl;

			cout << "后序遍历结果:";
			BT.PostOrder();
			cout << endl;

			cout << "层序遍历结果:";
			BT.LevelOrder();
			cout << endl;
			break;
		}
		case 2:
		{
			cout << "结点总数为:" << BT.Count() << endl
				<< "叶子结点总数:" << BT.leafNodeCount() << endl <<
				"单分支结点总数:" << BT.singleNodeCount() << endl <<
				"双分支结点总数:" << BT.doubleNodeCount() << endl;
			cout << "树高为:" << BT.Height() << endl;
			break;
		}
		case 3:
		{
			cout << "输入关键值:";
			char s;	cin >> s;
			flag = BT.Search(s);
			break;
		}
		case 4:
		{
			cout << "输入结点";
			char s;	cin >> s;
			flag = BT.SearchParent(s);
			break;
		}
		case 5:
		{
			op = -1;
			break;
		}
		}

		if (!flag)
		{
			cout << "操作失败" << endl;
			cout << "---------------------------\n";
		}
		if (op == -1)	break;

		cout << endl;
	}
	return;
}
int main()
{
	ios::sync_with_stdio(false);
	cin.tie(0), cout.tie(0);

	while (1)
	{
		cout << "1.根据带空指针标记的先序遍历序列构造对象--------" << endl;
		cout << "2.根据先序遍历和中序遍历序列构造对象--------" << endl;
		cout << "3.退出--------" << endl;
		cout << "请输入操作:" << endl;
		int t; cin >> t;

		if (t == 1) {
			cout << "输入带空指针标记(*)的先序序列:";
			string str;	cin >> str;
			vector<char> pre;
			for (int i = 0; i < str.size(); i++)
				pre.push_back(str[i]);
			BiTree<char> BT(pre);
			operate(BT);
		}
		else if (t == 2) {
			cout << "输入先序序列和中序序列:";
			string str;	cin >> str;
			vector<char> pre;
			for (int i = 0; i < str.size(); i++)
				pre.push_back(str[i]);

			string str2;	cin >> str2;
			vector<char> mid;
			for (int i = 0; i < str2.size(); i++)
				mid.push_back(str2[i]);

			BiTree<char> BT(pre, mid);
			operate(BT);
		}
		else {
			break;
		}
	}

	return 0;
}

测试结果

1.根据带空指针标记的先序遍历序列构造对象--------
2.根据先序遍历和中序遍历序列构造对象--------
3.退出--------
请输入操作:
1
输入带空指针标记(*)的先序序列:abd**e**cf***
---------------------------
请选择需要进行的操作
1. 用四种方法遍历二叉树
2. 计算结点总数、叶子结点总数、单分支结点数、双分支结点数和树高
3. 根据关键值查找结点
4. 求某个结点的父节点
5. 退出当前操作
---------------------------
1
先序遍历结果:a b d e c f
中序遍历结果:d b e a f c
后序遍历结果:d e b f c a
层序遍历结果:a b c d e f

---------------------------
请选择需要进行的操作
1. 用四种方法遍历二叉树
2. 计算结点总数、叶子结点总数、单分支结点数、双分支结点数和树高
3. 根据关键值查找结点
4. 求某个结点的父节点
5. 退出当前操作
---------------------------
2
结点总数为:6
叶子结点总数:3
单分支结点总数:1
双分支结点总数:2
树高为:3

---------------------------
请选择需要进行的操作
1. 用四种方法遍历二叉树
2. 计算结点总数、叶子结点总数、单分支结点数、双分支结点数和树高
3. 根据关键值查找结点
4. 求某个结点的父节点
5. 退出当前操作
---------------------------
3
输入关键值:a
该结点为:a

---------------------------
请选择需要进行的操作
1. 用四种方法遍历二叉树
2. 计算结点总数、叶子结点总数、单分支结点数、双分支结点数和树高
3. 根据关键值查找结点
4. 求某个结点的父节点
5. 退出当前操作
---------------------------
4
输入结点b
该结点的父结点为:a

---------------------------
请选择需要进行的操作
1. 用四种方法遍历二叉树
2. 计算结点总数、叶子结点总数、单分支结点数、双分支结点数和树高
3. 根据关键值查找结点
4. 求某个结点的父节点
5. 退出当前操作
---------------------------
5
1.根据带空指针标记的先序遍历序列构造对象--------
2.根据先序遍历和中序遍历序列构造对象--------
3.退出--------
请输入操作:
2
输入先序序列和中序序列:abdecf dbeafc
---------------------------
请选择需要进行的操作
1. 用四种方法遍历二叉树
2. 计算结点总数、叶子结点总数、单分支结点数、双分支结点数和树高
3. 根据关键值查找结点
4. 求某个结点的父节点
5. 退出当前操作
---------------------------
1
先序遍历结果:a b d e c f
中序遍历结果:d b e a f c
后序遍历结果:d e b f c a
层序遍历结果:a b c d e f

---------------------------
请选择需要进行的操作
1. 用四种方法遍历二叉树
2. 计算结点总数、叶子结点总数、单分支结点数、双分支结点数和树高
3. 根据关键值查找结点
4. 求某个结点的父节点
5. 退出当前操作
---------------------------
2
结点总数为:6
叶子结点总数:3
单分支结点总数:1
双分支结点总数:2
树高为:3

---------------------------
请选择需要进行的操作
1. 用四种方法遍历二叉树
2. 计算结点总数、叶子结点总数、单分支结点数、双分支结点数和树高
3. 根据关键值查找结点
4. 求某个结点的父节点
5. 退出当前操作
---------------------------
3
输入关键值:f
该结点为:f

---------------------------
请选择需要进行的操作
1. 用四种方法遍历二叉树
2. 计算结点总数、叶子结点总数、单分支结点数、双分支结点数和树高
3. 根据关键值查找结点
4. 求某个结点的父节点
5. 退出当前操作
---------------------------
3
输入关键值:p
未找到该结点
操作失败
---------------------------

---------------------------
请选择需要进行的操作
1. 用四种方法遍历二叉树
2. 计算结点总数、叶子结点总数、单分支结点数、双分支结点数和树高
3. 根据关键值查找结点
4. 求某个结点的父节点
5. 退出当前操作
---------------------------
4
输入结点p
该结点无父结点
操作失败
---------------------------

---------------------------
请选择需要进行的操作
1. 用四种方法遍历二叉树
2. 计算结点总数、叶子结点总数、单分支结点数、双分支结点数和树高
3. 根据关键值查找结点
4. 求某个结点的父节点
5. 退出当前操作
---------------------------
4
输入结点a
该结点无父结点
操作失败
---------------------------

---------------------------
请选择需要进行的操作
1. 用四种方法遍历二叉树
2. 计算结点总数、叶子结点总数、单分支结点数、双分支结点数和树高
3. 根据关键值查找结点
4. 求某个结点的父节点
5. 退出当前操作
---------------------------
5
1.根据带空指针标记的先序遍历序列构造对象--------
2.根据先序遍历和中序遍历序列构造对象--------
3.退出--------
请输入操作:
3

程序异常终止

可能是输入序列不正确构成二叉树的原因。#输入的数据一定要保证能构成正确的二叉树#

基本知识点总结

二叉树是一种常用的树形数据结构,它由节点(Node)组成,每个节点最多有两个子节点,分别称为左子节点和右子节点。

1. 二叉树的基本概念:

   - 根节点(Root):二叉树的顶层节点。

   - 叶子节点(Leaf):没有子节点的节点。

   - 父节点(Parent):有子节点的节点。

   - 子节点(Child):在父节点下方的节点。

   - 兄弟节点(Sibling):具有相同父节点的节点。

   - 深度(Depth):从根节点到当前节点的路径长度。

   - 高度(Height):根节点到最远叶子节点的路径长度。

2. 二叉树的分类:

   - 满二叉树:除了叶子节点外,所有节点都有两个子节点,并且所有叶子节点在同一层级上。

   - 完全二叉树:除了最后一层外,其他层节点全部填满,并且最后一层的节点从左到右依次填充。

3. 二叉树的遍历:

   - 前序遍历(Pre-order):根节点 -> 左子树 -> 右子树。

   - 中序遍历(In-order):左子树 -> 根节点 -> 右子树。

   - 后序遍历(Post-order):左子树 -> 右子树 -> 根节点。

   - 层序遍历(Level-order):逐层遍历,从左到右依次访问每个节点。

4. 二叉搜索树(Binary Search Tree,BST):

   - 二叉搜索树是一种特殊的二叉树,它满足以下条件:

     - 左子树上的所有节点的值小于根节点的值。

     - 右子树上的所有节点的值大于根节点的值。

     - 左右子树也分别是二叉搜索树。

   - 在二叉搜索树中,查找、插入和删除操作的时间复杂度为O(log n)。

5. 平衡二叉树(Balanced Binary Tree):

   - 平衡二叉树是一种特殊的二叉搜索树,它的左子树和右子树的高度差不超过1。

   - 常见的平衡二叉树包括红黑树、AVL树等,通过平衡操作保持树的平衡性。

6. 二叉树的应用:

   - 二叉树广泛应用于数据结构和算法中,例如排序算法、查找算法、哈夫曼编码等。

   - 表达式树(Expression Tree):用于解析和计算数学表达式。

   - 文件系统的目录结构:每个目录都可以看作是一个节点,子目录和文件为其子节点。

  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值