中文字幕av专区_日韩电影在线播放_精品国产精品久久一区免费式_av在线免费观看网站

溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務條款》

二叉樹的簡單遞歸實現(創建,遍歷,高度,大小)

發布時間:2020-10-17 07:03:38 來源:網絡 閱讀:3247 作者:羌笛夜 欄目:編程語言

二叉樹

二叉樹:二叉樹是一棵特殊的樹,二叉樹每個節點最多有兩個孩子結點,分別稱為左孩子和右孩子


滿二叉樹:高度為N的滿二叉樹有2^N - 1個節點的二叉樹。

二叉樹的簡單遞歸實現(創建,遍歷,高度,大小)

完全二叉樹: 若設二叉樹的深度為h,除第 h 層外,其它各層 (1~h-1) 的結點數都達到最大個數,第 h 層所有的結點都連續集中在最左邊,這就是完全二叉樹

二叉樹的簡單遞歸實現(創建,遍歷,高度,大小)

二叉樹的存儲結構

數組表示存儲

二叉樹的簡單遞歸實現(創建,遍歷,高度,大小)

鏈表存儲表示:

    數組表示法用于完全二叉樹的存儲非常有效,但表示一般的二叉樹則不是很理想。此外,在一棵樹中進行插入和刪除時,為了反映節點的層次變化,可能需要移動許多節點,降低了算法效率,二使用連接表示,可以克服這些缺點。

    根據二叉樹的定義,可以設計出二叉樹的節點結構。二叉樹的每一個節點有三個域:數據域_data,左子女節點指針_leftChild,右子女節點指針_rightChild。這中鏈表稱為二叉鏈表。使用這種結構,可以很方便的根據左右孩子指針找到他的左右孩子。但要找到他的雙親很難。為了找到雙親節點,可以在節點中在增加一個雙親指針域_parent,他被稱為三叉鏈表結構。

二叉樹的簡單遞歸實現(創建,遍歷,高度,大小)


樓主主要實現的是二叉鏈表結構

節點的定義

//節點結構
template<class T>
struct BinaryTreeNode
{
	//構造函數 
	BinaryTreeNode(const T& data)
		:_data(data)
		,_leftChild(NULL)
		,_rightChild(NULL)
	{}
public:
	T _data;//數據域
	BinaryTreeNode* _leftChild;//左孩子指針
	BinaryTreeNode* _rightChild;//右孩子指針
};

 

二叉樹的實現

//二叉樹類
template<class T>
class BinaryTree
{
	typedef BinaryTreeNode<T> Node;
public:
	BinaryTree()
		:_root(NULL)
	{}
	//構造函數
	BinaryTree(const T* a, size_t size, const T& invalid)
	{
		assert(a);
		size_t index = 0;
		_root = _CreateTree(a, size, invalid,index);
	}
	//拷貝構造
	BinaryTree(const BinaryTree<T>& t)
	{
		_root = _Copy(t._root);
	}
	//賦值運算符的重載
	BinaryTree<T>& operator=(BinaryTree<T> t)
	{
		swap(_root, t._root);
		return *this;
	}
	//析構函數
	~BinaryTree()
	{
		_Destory(_root);
	}

public:
	//前序遍歷
	void PrevOrder()
	{
		_PrevOrder(_root);
		cout << endl;
	}
	//中序遍歷
	void InOrder()
	{
		_InOrder(_root);
		cout << endl;
	}
	//后序遍歷
	void PostOrder()
	{
		_PostOrder(_root);
		cout << endl;
	}
	//層次遍歷
	void LevelOrder()
	{
		_LevelOrder(_root);
		cout << endl;
	}
	//求二叉樹的節點個數
	size_t Size()
	{
		return _Size(_root);
	}
	//求二叉樹的深度
	size_t Depth()
	{
		return _Depth(_root);
	}
	//求二叉樹的葉子節點的個數
	size_t LeafSize()
	{
		return _LeafSize(_root);
	}
protected:
	Node* _CreateTree(const T* a, size_t size, const T& invalid,  size_t&  index)
		//index要傳引用,需要更改index的值
	{
		Node* root = NULL;
		//判斷數組是否越界和輸入的值是否合法
		if (index < size&&a[index] != invalid)
		{
			root = new Node(a[index]);//創建根節點
			root->_leftChild = _CreateTree(a, size, invalid, ++index);//遞歸創建左子樹
			root->_rightChild = _CreateTree(a, size, invalid, ++index);//遞歸創建右子樹
		}
		return root;//返回根節點
	}

	void _PrevOrder(Node* root)
	{
		//如果節點為空則直接返回
		if (root == NULL)
		{
			return;
		}

		cout << root->_data << " ";//訪問根節點
		_PrevOrder(root->_leftChild);//遞歸訪問左子樹
		_PrevOrder(root->_rightChild);//遞歸訪問右子樹
	}

	void _InOrder(Node* root)
	{
		//如果節點為空則直接返回
		if (root == NULL)
		{
			return;
		}

		_InOrder(root->_leftChild);//訪問左子樹
		cout << root->_data << " ";//遞歸訪問根節點
		_InOrder(root->_rightChild);//遞歸訪問右子樹
	}

	void _PostOrder(Node* root)
	{
		//如果節點為空則直接返回
		if (root == NULL)
		{
			return;
		}

		_PostOrder(root->_leftChild);//訪問左子樹
		_PostOrder(root->_rightChild);//遞歸訪問右子樹
		cout << root->_data << " ";//遞歸訪問根節點
	}

	//層次遍歷
	void _LevelOrder(Node* root)
	{
		if (root == NULL)
		{

			return;
		}
		queue<Node*> q;
		q.push(root);//根節點入隊
		while (!q.empty())//當隊列不為空
		{
			if (q.front()->_leftChild)
			{
				q.push(q.front()->_leftChild);
			}
			if (q.front()->_rightChild)
			{
				q.push(q.front()->_rightChild);
			}
			cout << q.front()->_data << " ";
			q.pop();
		}
	}

	size_t _Size(Node* root)
	{
		size_t count = 0;
		if (root == NULL)
		{
			return count;//樹為空
		}

		count++;//根節點
		count += _Size(root->_leftChild);//計算左子樹大小
		count+= _Size(root->_rightChild);//計算右子樹大小
		return count;
	}


	//返回左右子樹深度較大的
	size_t _Depth(Node* root)
	{
		if (root == NULL)
		{
			return 0;
		}
		size_t LeftDepth = _Depth(root->_leftChild);
		size_t RightDepth= _Depth(root->_rightChild);
		if (LeftDepth > RightDepth)
		{
			return ++LeftDepth;
		}
		else
		{
			return ++RightDepth;
		}
	}

	size_t _LeafSize(Node*root)
	{
		if (root == NULL)
		{
			return 0;
		}
		if (root->_leftChild == NULL && root->_rightChild == NULL)
		{
			return 1;
		}

		return _LeafSize(root->_leftChild)+ _LeafSize(root->_rightChild);
	}

	Node* _Copy(Node* root)
	{
		
		if (root == NULL)
		{

			return NULL;
		}

		Node* newRoot = new Node(root->_data);
		newRoot->_leftChild = _Copy(root->_leftChild);
		newRoot->_rightChild = _Copy(root->_rightChild);
		return newRoot;
	}

	void _Destory(Node* root)
	{
		if (root == NULL)
		{
			return;
		}

		//刪除葉結點
		if (root->_leftChild == NULL&&root->_rightChild == NULL)
		{
			delete root;
			root = NULL;
			return;
		}

		_Destory(root->_leftChild);//遞歸刪除左子樹
		_Destory(root->_rightChild);//遞歸刪除右子樹
		delete root;
	}
private:
	BinaryTreeNode<T>* _root;//根節點
};


測試代碼

#include"BinaryTree.h"

void TestBinary()
{
	/*int a1[10] = { 1,2,3,'#','#',4,'#','#',5,6 };
	BinaryTree<int> t1(a1, 10, '#');
	cout << "先序遍歷:";
	t1.PrevOrder();
	cout << "中序遍歷:";
	t1.InOrder();
	cout << "后序遍歷:";
	t1.PostOrder();
	cout << "層次遍歷:";
	t1.LevelOrder();
	cout << "size:" << t1.Size() << endl;
	cout << "depth:" << t1.Depth() << endl;
	cout << "leafSize:" << t1.LeafSize() << endl;*/

	int a2[15] = { 1,2,'#',3,'#','#',4,5,'#',6 ,'#' ,7,'#' ,'#' ,8 };
	int a[] = { 1,2,'#','#',3 };
	BinaryTree<int> t1(a, 5, '#');
	BinaryTree<int> t2;
	t2 = t1;
	cout << "先序遍歷:"; 
	t2.PrevOrder();
	cout << "中序遍歷:";
	t2.InOrder();
	cout << "后序遍歷:";
	t2.PostOrder();
	cout << "層次遍歷:";
	t2.LevelOrder();
	cout << "size:" << t2.Size() << endl;
	cout << "depth:" << t2.Depth() << endl;
	cout << "leafSize:" << t2.LeafSize() << endl;
}
int main()
{
	TestBinary();
	getchar();
	return 0;
}

測試結果

二叉樹的簡單遞歸實現(創建,遍歷,高度,大小)




向AI問一下細節

免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。

AI

武邑县| 湘潭市| 宜黄县| 云龙县| 永顺县| 肇源县| 晋宁县| 栾城县| 石屏县| 万全县| 武陟县| 黔南| 通榆县| 呼图壁县| 泰安市| 沅江市| 曲水县| 达孜县| 广宁县| 城固县| 都匀市| 安宁市| 邹平县| 桑植县| 突泉县| 鄂托克前旗| 治多县| 阿克陶县| 崇州市| 孝昌县| 利津县| 托克托县| 伊通| 高州市| 诸暨市| 兰坪| 鹤岗市| 谢通门县| 五大连池市| 辽中县| 腾冲县|