1. 程式人生 > >二叉樹的建立及遍歷(先序遍歷、中序遍歷、後續遍歷、層次遍歷)

二叉樹的建立及遍歷(先序遍歷、中序遍歷、後續遍歷、層次遍歷)

資料結構學過有一段時間了,太長時間沒有寫程式碼,基本上都忘個差不多了,最近用到了,今天重新複習了一下,寫個二叉樹小彙總

注:我這裡節點是字元型別,所以如果節點要是儲存大於9的數字的值的話,需要將其改一下,部分功能程式碼也要隨之改變,但是隻要思想弄懂了,那麼無論改成什麼樣的資料型別,都應該是沒有問題的!

大家也可以自己寫一個試試!!!!

二叉樹的建立①:(用擴充套件先序遍歷序列建立二叉樹)

#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>

using namespace std;

typedef struct Node{
	char data;
	struct Node * LChild;
	struct Node * RChild;
}BitNode,* BiTree; 


void Creat(BiTree &T){  //  &T  這點是一個引用,是一個指標的引用  在這裡面對指標的修改也就是對原指標的修改 
	char ch;
	cin >> ch;
	if(ch == '#')         //  建立樹的時候輸入為 # 時說明該分支為NULL
	 	T = NULL;
	else{
		T = new BitNode;
		T->data = ch;
		Creat(T->LChild);
		Creat(T->RChild);
	}
}

int main()
{
	BiTree T;    //   建立一個指向二叉樹根節點的指標
	cout << "建樹 :(請輸入樹的結構(abd##e##cf###)也就是擴充套件前序遍歷)" << endl; 
	Creat(T);
	cout << "二叉樹已建立好!!!!!!!!!!!!!!!!!" << endl;
	return 0;
} 
二叉樹建立②:(根據先序遍歷和中序遍歷建立二叉樹)
#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>

using namespace std;

typedef struct Node{
	char data;
	struct Node * LChild;
	struct Node * RChild;
}BitNode,* BiTree; 


BitNode * Creat(string pre,string mid)
{
	BiTree T = NULL;
	if(pre.length() > 0)
	{
		T = new BitNode;
		T->data = pre[0];
		/*  查詢pre[0] 在中序遍歷中的位置,*/
		int index = mid.find(pre[0]);   
		/*有中序遍歷可以推出,前序遍歷中1-index個都是左子樹的,
		  index + 1 到 pre.length 是右子樹的*/
		
		//  前 1 - index個是左子樹,建立左子樹 
		T->LChild = Creat(pre.substr(1,index),mid.substr(0,index)); 
		// 從  index 結束為右子樹,建立右子樹 
		T->RChild = Creat(pre.substr(index + 1),mid.substr(index + 1));
		/*    std::string::substr
		 *    string substr (size_t pos = 0, size_t len = npos)   
		 *    pos : 開始的位置(預設為 0)        
		 *    len : 偏移量,即從開始的位置數 len 長度個字元 (預設到字串的結束) 
		 */
	}
	return T;
}

int main()
{
	string pre,mid,post;  // 前序遍歷 、中序遍歷、後序遍歷
	cout << "根據輸入的前序和中序建樹" << endl;
	cout << "請輸入前序遍歷(字串,中間不要用空格之類的符號 例:4312657):";
	cin >> pre;
	cout << endl << "請輸入中序遍歷(字串,中間不要用空格之類的符號 例:1234567):";
	cin >> mid;
	
	BiTree T = Creat(pre,mid);
	cout << "二叉樹已建立好!!!!!!!!!!!!!!!!!" << endl; 
	return 0;
}



二叉樹建立③:(根據後序遍歷和中序遍歷建立二叉樹)
#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <queue>
using namespace std;

typedef struct Node{
	char data;
	struct Node * LChild;
	struct Node * RChild;
}BitNode,* BiTree; 


BitNode * Creat(string post,string mid)
{
	BiTree T = NULL;
	if(post.length() > 0)
	{
		T = new BitNode;
		T->data = post[post.length() - 1];
		//  查詢pre[0] 在中序遍歷中的位置,
		int index = mid.find(post[post.length() - 1]);  
		/*有中序遍歷可以得到後序遍歷中1-index個都是左子樹的,
		  index + 1 到 pre.length 是右子樹的  */
		
		//  前 1 - index個是左子樹,建立左子樹 
		T->LChild = Creat(post.substr(0,index)
		,mid.substr(0,index)); 
		// 從  index 結束為右子樹,建立右子樹 
		T->RChild = Creat(post.substr(index
		,mid.length() - 1 - index),mid.substr(index+1));
		/*    std::string::substr
		 *    string substr (size_t pos = 0, size_t len = npos)   
		 *    pos : 開始的位置(預設為 0)        
		 *    len : 偏移量,即從開始的位置數 len 長度個字元 (預設到字串的結束) 
		 */
	}
	return T;
}

int main()
{
	string pre,mid,post;  // 前序遍歷 、中序遍歷、後序遍歷

	cout << "根據輸入的後序和中序建樹" << endl;
	cout << "請輸入後序遍歷(字串,中間不要用空格之類的符號 例:2315764):";
	cin >> post;
	cout << endl << "請輸入中序遍歷(字串,中間不要用空格之類的符號 例:1234567):";
	cin >> mid;   //  輸入後續和中序建立二叉樹 
	BiTree T = Creat(post,mid);
	cout << "二叉樹已建立好!!!!!!!!!!!!!!!!!" << endl;
	return 0;
} 




二叉樹的遍歷:(前、中、後 及 層次遍歷)
/*
 *   在遍歷的過程中,前中後都是針對父親來說的,輸出的時候,每個節點都是作為父親節點輸出的 
 */

// 前序遍歷      先父親節點先遍歷 ,即先父親,再左兒子,最後是右兒子  
void preorder(BiTree T)
{
	if(T)
	{
		cout << T->data << " ";
		preorder(T->LChild);
		preorder(T->RChild);
	}
}
// 中序遍歷      父親節點在中間遍歷, 即先左兒子,再父親,最後是右兒子 
void midorder(BiTree T)
{
	if(T)
	{
		midorder(T->LChild);
		cout << T->data << " ";
		midorder(T->RChild); 
	}
}
// 後續遍歷      父親節點在最後遍歷, 即先左兒子,再右兒子,最後是父親 
void postorder(BiTree T)
{
	if(T)
	{
		postorder(T->LChild);
		postorder(T->RChild);
		cout << T->data << " ";
	}
}

/*
 *  層次遍歷,利用佇列進行層次遍歷,遍歷到某個節點,
 *  如果該節點有左孩子,右孩子,那麼就將其孩子放入佇列中 
 */
void Levelorder(BiTree T)
{
	queue<BiTree>Q;
	BiTree t;
	Q.push(T);
	while(!Q.empty())
	{
		t = Q.front();
		Q.pop();
		cout << t->data << " ";
		if(t->LChild)
		{
			Q.push(t->LChild);
		}
		if(t->RChild)
		{
			Q.push(t->RChild);
		}
	}
}