1. 程式人生 > >c++實現二叉樹及筆試題(1)

c++實現二叉樹及筆試題(1)

1.建立二叉樹
2.前序遍歷<遞迴與非遞迴>
3.中序遍歷<遞迴與非遞迴>
4.後序遍歷<遞迴與非遞迴>
5.層次遍歷 

6.獲得節點葉子的個數
7.二叉樹獲得的高度
8.二叉樹交換的左右兒子
9.求兩個節點pNode1和pNode2在以[R為樹根的樹中的最近公共祖先
10.判斷一個節點t是否在以r為根的子樹中
11.求兩個節點的最近公共祖先;
12.求二叉樹中最遠的兩個節點的距離;即求寬度
BinaryTree.h

//#pragma once
#ifndef  _BINARYTREE_H
#define _BINARYTREE_H

#include<iostream>
#include<queue>
#include<stack>
#include<deque>
using namespace std;
template <class T>
class BinTreeNode
{
public:
	BinTreeNode() :left(NULL), right(NULL) {}
	BinTreeNode(T v) :left(NULL), right(NULL), data(v) {}
	~BinTreeNode(){}


public:
	T data;
	BinTreeNode<T> *left, *right;
};

template <class T>
class BinaryTree
{
public:
	BinaryTree(T v) :root(NULL),flag(v) {}
public:
	void CreateBinTree(const T *&str)
	{
		CreateBinTree(root, str);
	}
	//樹的葉子結點數
	int LeafSize()const { return LeafSize(root); }
	//樹的結點數
	int size() { return size(root); }
	//樹的高度
	int height() { return height(root); }
	//樹的高度
	int Weight() { return Weight(root); }
	/*********************採用遞迴*********************************************/
	void PreOrder() const{PreOrder(root);}//前序遍歷
	void InOrder()const {InOrder(root);}//中序遍歷
	void PostOrder()const {PostOrder(root);}//後序遍歷
	void LeveLOrder() const { LeveLOrder(root); }//層遍歷
	/*********************採用非遞迴*******************************************/
	void Non_Recursive_PreOrder()const { Non_Recursive_PreOrder(root); }
	void Non_Recursive_InOrder() const { Non_Recursive_InOrder(root); }
	void Non_Recursive_PostOrder()const { Non_Recursive_PostOrder(root); }
	/*************************************************************************/
	
	//判斷值是否存在在節點中
	bool IsInTree(const T&key)
	{
		return IsInTree(root, key);
	}
	//交換左右子數
	void SwapLeftRightChild() { SwapLeftRightChild(root); }
	//求兩個結點的最近的父節點
	BinTreeNode<T>* CommonParent(const T &x, const T &y)
	{
		BinTreeNode<T> *px = Find(root, x);
		BinTreeNode<T> *py = Find(root, y);
		if (px == NULL || py == NULL)
		{
			return NULL;
		}
		return CommonParent(root, px, py);
	}
	//查詢結點
	BinTreeNode<T>* Find(const T &key)
	{
		return Find(root, key);
	}
	//求一個結點的父結點
	BinTreeNode<T>*Parent(const T &key)
	{
		BinTreeNode<T> *p = Find(root, key);
		if (p == NULL)
			return NULL;
		return Parent(root, p);
	}
protected:
	int Weight(BinTreeNode<T> *t)const
	{
		if (t == NULL)
			return 0;
		deque<BinTreeNode<T> *> Q1, Q2;

		Q1.push_back(t);
		int max_weight = 1;
		int tmp_weight = 0;
		BinTreeNode<T> *p;
		while (!Q1.empty())
		{
			while (!Q1.empty())
			{
				p = Q1.front();
				Q1.pop_front();
				if (p->left != NULL)
					Q2.push_back(p->left);
				if (p->right != NULL)
					Q2.push_back(p->right);
			}
			tmp_weight = Q2.size();
			if (tmp_weight > max_weight)
			max_weight = tmp_weight;
			Q1 = Q2;
			Q2.clear();
		}
		return max_weight;
	}
	int LeafSize(BinTreeNode<T> *t)const
	{
		if (t == NULL)
			return 0;
		if (t->left == NULL && t->right == NULL)
			return 1;
		else
			return LeafSize(t->right) + LeafSize(t->right);

	}
	int size(BinTreeNode<T> *t )
	{
		if (t == NULL)
			return 0;
		else
			return size(t->left) + size(t->right) + 1;
	}
	int height(BinTreeNode<T> *root)
	{
		if (root == NULL)
			return 0;
		else
		{
			int m = height(root->left);
			int n = height(root->right);
			return (m > n ? m : n) + 1;
		}
	}
	BinTreeNode<T>* CommonParent(BinTreeNode<T>*t, BinTreeNode<T> *x, BinTreeNode<T> *y)
	{
		if (t == NULL)
			return NULL;
		if (IsInTree(x, y->data))return x;
		if (IsInTree(y, x->data))return y;
		BinTreeNode<T> *left, *right, *another_left, *another_right;
		left = IsInTree(t->left, x->data);
		right = IsInTree(t->right, y->data);
		another_left = IsInTree(t->left, y->data);
		another_right = IsInTree(t->right, x->data);

		if ((left&&right) || (another_right&&another_left))
			return t;
		else if (left&&another_left)
			return CommonParent(t->left, x, y);
		else if (right &&another_right)
			return CommonParent(t->right, x, y);
		else
			return NULL;
	}
	BinTreeNode<T>* Find(BinTreeNode<T> *t, const T &key)
	{
		if (t == NULL)
			return NULL;
		if (t->data == key)
			return t;
		BinTreeNode<T> *p = Find(t->left, key);
		if (p != NULL)
			return p;
		p = Find(t->right, key);
		return p;
	}
	BinTreeNode<T>*Parent(BinTreeNode<T> *t,BinTreeNode<T> *p)
	{
		if (t == NULL||p==t)
			return NULL;
		if (t->left == p || t->right == p)
			return t;
		else
		{
			BinTreeNode<T> *tmp = Parent(t->left,p);
			if (tmp != NULL)
				return tmp;
			return Parent(t->right, p);
		}
	}
	BinTreeNode<T>* IsInTree(BinTreeNode<T> *t, const T &key)
	{
		BinTreeNode<T>*p = Find(t, key);
		if (p != NULL)
			return p;
		else
			return NULL;
	}
	void SwapLeftRightChild(BinTreeNode<T> *&t)
	{
		if (t == NULL || (t->left == NULL && t->right == NULL))
			return;
		BinTreeNode<T> *ptmp = t->left;
		t->left = t->right;
		t->right = ptmp;
		SwapLeftRightChild(t->left);
		SwapLeftRightChild(t->right);
	}
	//////////////////////////////////////////////////////////////////////////
	void Non_Recursive_PreOrder(BinTreeNode<T> *t)const
	{
		
		if (t != NULL)
		{
			stack<BinTreeNode<T> *> s;
			s.push(t);
			BinTreeNode<T> *p;
			while (!s.empty())
			{
				p = s.top();
				s.pop();
				cout << p->data << " ";
				if (p->right != NULL)
					s.push(p->right);
				if (p->left != NULL)
					s.push(p->left);
			}
		}
	}
	void Non_Recursive_InOrder(BinTreeNode<T> *t)const
	{
		stack<BinTreeNode<T> *>s;
		BinTreeNode<T> *temp = t;
		while (temp || !s.empty())
		{
			while (temp)  //有右邊就要右邊左子樹入棧
			{
				s.push(temp);
				temp = temp->left;
			}
			temp = s.top();
			cout << temp->data << " ";
			s.pop();
			temp = temp->right;
		}
	}
	void Non_Recursive_PostOrder(BinTreeNode<T> *t)const
	{
		stack<BinTreeNode<T> *>s;
		BinTreeNode<T> *temp = root, *pre = NULL;
		while (temp || !s.empty())
		{
			while (temp)
			{
				s.push(temp);
				temp = temp->left;
			}
			temp = s.top();
			if (!temp->right || temp->right == pre)//判斷無右邊
			{
				cout << temp->data << " ";
				s.pop();
				pre = temp;
				temp = NULL;
			}
			else
				temp = temp->right;
		}
	}
	///////////////////////////////////////////////////////////////////////////
	void LeveLOrder(BinTreeNode<T> *t)const
	{
		if (t != NULL)
		{
			queue<BinTreeNode<T>*> Q;
			BinTreeNode<T> *p;
			Q.push(t);
			while (!Q.empty())
			{
				p = Q.front();
				Q.pop();
				cout << p->data << " ";
				if (p->left != NULL)
					Q.push(p->left);
				if (p->right != NULL)
					Q.push(p->right);
			}
		}
	}
	void PreOrder(BinTreeNode<T> *t)const
	{
		if (t != NULL)
		{
			cout << t->data << " ";
			PreOrder(t->left);
			PreOrder(t->right);
		}
	}
	void InOrder(BinTreeNode<T> *t)const
	{
		if (t != NULL)
		{
			InOrder(t->left);
			cout << t->data << " ";
			InOrder(t->right);
		}
	}
	void PostOrder(BinTreeNode<T> *t)const
	{
		if (t != NULL)
		{
			PostOrder(t->left);
			PostOrder(t->right);
			cout << t->data << " ";
		}
	}
	void CreateBinTree(BinTreeNode<T> *&t, const T *&str)
	{
		if (*str == flag || *str == '\0')
		{
			t = NULL;
		}
		else
		{
			t = new BinTreeNode<T>(*str);
			CreateBinTree(t->left, ++str);
			CreateBinTree(t->right, ++str);
		}
	}
private:
	T flag;
	BinTreeNode<T>* root;
};
#endif // ! _BINARYTREE_h

main.cpp中

#include"BinaryTree.h"
#include<stdio.h>
int main()
{
	BinaryTree<char> bt('#');
	const char *str = "ABC##DE##F##G#H##";
	bt.CreateBinTree(str);
	/*採用遞迴方法*/
	bt.PreOrder();    cout << endl;//前序遍歷
	bt.InOrder();     cout << endl;//中序遍歷
	bt.PostOrder();   cout << endl;//後序遍歷
    /*採用非遞迴方法*/
	bt.Non_Recursive_PreOrder();    cout << endl;//前序遍歷
	bt.Non_Recursive_InOrder();     cout << endl;//中序遍歷
	bt.Non_Recursive_PostOrder();   cout << endl;//後序遍歷
	bt.SwapLeftRightChild();
	bt.PostOrder(); cout << endl;
	BinTreeNode<char>*pt = bt.CommonParent('E','G');
	cout << "size:" << bt.size() << endl;
	cout << "height:" << bt.height() << endl;
	cout << "LeafSize:" << bt.LeafSize() << endl;
	cout << "Weight:" << bt.Weight() << endl;
	return 0;
}

相關推薦

c++實現試題1

1.建立二叉樹2.前序遍歷<遞迴與非遞迴> 3.中序遍歷<遞迴與非遞迴> 4.後序遍歷<遞迴與非遞迴> 5.層次遍歷  6.獲得節點葉子的個數7.二叉樹獲得的高度8.二叉樹交換的左右兒子9.求兩個節點pNode1和pNode2在以[R為樹

C#實現的遍歷

c# 遍歷 二叉樹 遞歸 循環 C#實現二叉樹的前序、中序、後序遍歷。public class BinaryTreeNode { int value; BinaryTreeNode left; BinaryTreeNode r

c++實現層序、前序創建,遞歸非遞歸實現遍歷

log ios cst ack ret 出棧 隊列 結點 非遞歸實現 #include <iostream> #include <cstdio> #include <stdio.h> #include <string> #i

資料結構實驗6:C++實現

實驗6 學號:     姓名:      專業:   6.1 實驗目的 掌握二叉樹的動態連結串列儲存結構及表示。 掌握二叉樹的三種遍歷演算法(遞迴和非遞迴兩類)。 運用二叉樹三種遍歷的方法求解有關問題。 6

C++實現建立、前序、中序、後序、層序遍歷

看完資料結構二叉樹部分後,通過學習書上的虛擬碼以及其他人的程式碼自己動手實現了一下,採用前序方式建立一顆二叉樹,實現了前中後層四種遍歷方式。 在層序遍歷部分與前三種遍歷不同,層序遍歷採用從根節點開始從上到下逐層遍歷,所以藉助佇列來實現,開始遍歷後,將根節點先壓入佇列,然後將

學習筆記 c++ 用類來實現的建立與遍歷

       程式碼: #include<iostream> #include<stdio.h> using namespace std; class BiTree { public:     char data;     BiTree *

c++實現的插入、刪除、查詢、遍歷和樹形列印

binary_tree.h 宣告 #ifndef BINARY_TREE #define BINARY_TREE #include "util.h" template<typename T> class tree_node { public: tree_

C++實現的插入、刪除、查詢、遍歷

1.二叉樹的概念        樹是一些節點的集合,節點之間用邊連結,節點之間不能有環路。上層的節點稱為父節點,下層節點稱為子節點。最上層的節點稱為根節點。       二叉樹是特殊的樹。對於每個節點

C實現

建立介面/*tree.h -- 二叉查詢樹*/ #pragma once //只編譯一次 #define SLEN 20 /*根據具體情況定義Item*/ typedef struct item { char petname[SLEN];

C++實現的非遞迴前、中、後序遍歷

void NoRecursePreTraverse(BiTree tree){ stack<BiNode *> stack; BiNode *node = tree; while(node != NULL || !stack.empty

C#實現--連結串列結構

1 /// <summary> 2 /// 二叉搜尋樹:結點的左子節點的值永遠小於該結點的值,而右子結點的值永遠大於該結點的值 稱為二叉搜尋樹 3 /// </summary> 4 public class LinkBinarySear

C++實現的遞迴遍歷與非遞迴遍歷

基本上所有關於二叉樹的操作都是基於二叉樹的遍歷演算法來實現的,因此在這裡講一下二叉樹的遍歷演算法,其中包括遞迴與非遞迴演算法,在演算法中用輸出節點資料來代替對節點的操作。 首先給出這樣一棵數: 1、前序遍歷 所謂前序遍歷就是先對節點資料進行處理,然後才

C++實現的三種遍歷方式

- 非遞迴實現程式碼: #include<stdio.h> #include<stdlib.h> #include"data_structure.h" //建立一棵二叉樹 BTree create_tree() { BTree

資料結構與演算法——表示式類的C++實現()

表示式簡介: 表示式樹的樹葉是運算元,如數字或字母,而其它結點為操作符(+ - * / %等);由於這裡的操作都是二元的,所以這棵特定的樹正好是二叉樹。 下面這個樹的中綴表示式為:(a+b*c) + ((d*e + f)*g);(可以中序遍歷該表示式樹獲得該

python實現相關操作

最近秋招差不多結束了,這幾個月複習了不少東西,記錄一下用python構造二叉樹以及相關的操作,與二叉樹相關的操作大多數都可以用遞迴的方法來解決。本文將記錄二叉樹的前序遍歷、中序遍歷、後序遍歷、層次

C++實現連結串列

#include "stdafx.h" #include <iostream> #include <deque> using namespace std; template<typename T> struct TreeNode{

C++實現的遞迴與非遞迴遍歷

#include<iostream> #include<stdlib.h> #include<stack> #include<queue> using namespace std; typedef char ElemType; //二叉樹的二叉連結串列結構,

實例學習——更新節點祖輩節點高度

節點類 rtu new 指針 endif 圖片 實例 out ren 在第(四)節獲取節點高度函數getHeight()函數的基礎上,增添並測試更新節點高度函數和更新祖輩節點高度函數:updateHight()、updateAboveHei()。在上節中,每插入一個新節點,

python實現層次遍歷寬度優先遍歷或叫廣度優先遍歷

1、何為層次遍歷       說白了,就是一層一層、由上至下、由左至右的搜尋遍歷二叉樹中的元素。                上面這個二叉樹,那麼層次遍歷的輸出應該是:1、2、

java實現的遍歷遞迴和非遞迴

現有一顆如下圖所示的二叉樹: 其遍歷的各種方式如下: 構造一顆如下圖所示的二叉樹,用java實現其前序,中序,後序遍歷 注意二叉樹節點的定義如下: public clas