完全二叉樹的三種遍歷(二)--- 順序存儲

上篇文章中已經貼了二叉樹三種遍歷的遞歸及非遞歸的實現代碼,那這篇文章是幹什麼的呢?嗯,雖然不論是二叉樹的順序存儲還是二叉樹的鏈式存儲,三種遍歷的思路都是一樣的,但是在寫代碼的時候仍然還要注意邊界,所以決定也貼出來吧,好查找唄^O^

來,繼續上篇文章的樹,二叉樹的順序存儲就是在數組中存儲。在代碼上看起來就是一個數組,我們之所以說它是二叉樹,意味着,在這篇文章中,邏輯意義上我們將它看成一顆樹!!你會注意到上篇文章的樹不是一個完全二叉樹,所以在數組中存儲起來很浪費空間,所以本篇說的都是完全二叉樹的順序存儲哦!

如下:有一個完全二叉樹:


一顆樹,我們將它按層從上往下,每層從左往右依次存到數組中去。當然你也可以從數組的1號下標開始存儲喔~,我就直接從0號下標開始存儲咯!

根結點與左右孩子索引的關係如下!!!


/*********************************************************************/
//先序遍歷的遞歸
void PreTravel1(char *arr,int parentindex,int len)
{
	if(parentindex<=len-1)
	{
		cout<<arr[parentindex]<<" ";
		PreTravel1(arr,parentindex*2+1,len);
		PreTravel1(arr,parentindex*2+2,len);
	}
}

//先序遍歷的非遞歸
void PreTravel2(char* arr,int parentindex,int len)
{
	//1
	//stack<char> st;
	
	//while(1)
	//{
	//	if(st.empty() && parentindex>len-1)
	//		break;
	//	if(parentindex<=len-1 )
	//	{
	//		st.push(parentindex);
	//		cout<<arr[parentindex]<<" ";
	//		parentindex=parentindex*2+1;
	//	}
	//	else
	//	{
	//		parentindex=st.top();
	//		parentindex=parentindex*2+2;
	//		st.pop();
	//	}
	//}
	//1使用隊列
	//deque<char> que;
	//que.push_back(parentindex);
	//while(!que.empty())
	//{
	//	parentindex=que.front();que.pop_front();
	//	cout<<arr[parentindex]<<" ";
	//	if(parentindex*2+1<=len)
	//		que.push_back(parentindex*2+2);
	//	if(parentindex*2+2<=len)
	//		que.push_back(parentindex*2+1);
	//}

	//2使用棧
	stack<char> st;
	while(!st.empty() || parentindex<=len-1)
	{
		while(parentindex<=len-1)
		{
			st.push(parentindex);
			cout<<arr[parentindex]<<" ";
			parentindex=parentindex*2+1;
		}
		parentindex=st.top();
		parentindex=parentindex*2+2;
		st.pop();
	}
}
void Pre(char *arr,int len)
{
	if(arr==NULL || len<=0)
		return ;
	PreTravel1(arr,0,len);
	//PreTravel2(arr,0,len);
}
/*********************************************************************/
//中序遍歷的遞歸實現
void InTravel1(char* arr,int parentindex,int len)
{
	if(parentindex<=len-1)
	{
		InTravel1(arr,parentindex*2+1,len);
		cout<<arr[parentindex]<<" ";
		InTravel1(arr,parentindex*2+2,len);
	}
}
//中序遍歷的非遞歸實現
void InTravel2(char* arr,int parentindex,int len)
{
	stack<char> st;
	
	while(!st.empty() || parentindex<=len-1)
	{
		while(parentindex<=len-1)
		{
			st.push(parentindex);
			parentindex=parentindex*2+1;
		}
		parentindex=st.top();
		cout<<arr[parentindex]<<" ";
		st.pop();
		parentindex=parentindex*2+2;
	}
}
void In(char *arr,int len)
{
	if(arr==NULL || len<=0)
		return ;
	InTravel1(arr,0,len);
	//InTravel2(arr,0,len);
}
/*********************************************************************/
//後序遍歷的遞歸實現
void PostTravel1(char *arr,int parentindex,int len)
{
	if(parentindex<=len-1)
	{
		PostTravel1(arr,parentindex*2+1,len);
		PostTravel1(arr,parentindex*2+2,len);
		cout<<arr[parentindex]<<" ";
	}
}
//後序遍歷的非遞歸實現
void PostTravel2(char* arr,int parentindex,int len)
{
	stack<char> st;
	int tag=-1;
	while(!st.empty() || parentindex<=len-1)
	{
		while(parentindex<=len-1)
		{
			st.push(parentindex);
			parentindex=parentindex*2+1;
		}
		parentindex=st.top();st.pop();
		if(parentindex*2+2==tag || parentindex*2+2>len-1)
		{
			cout<<arr[parentindex]<<" ";
			tag=parentindex;
			parentindex=len;
		}
		//parentindex=parentindex*2+2;
		else
		{
			st.push(parentindex);
			parentindex=parentindex*2+2;
		}
	}
}

void Post(char *arr,int len)
{
	if(arr==NULL && len<=0)
		return ;
	PostTravel1(arr,0,len);
	//PostTravel2(arr,0,len);
}
/*********************************************************************/
int main()
{
	char arr[]={'A','B','C','D','E','F','G','H'};
	int len=sizeof(arr)/sizeof(arr[0]);
	
	cout<<"PreTravel: ";
	Pre(arr,len);
	cout<<endl;

	cout<<"InTravel: ";
	In(arr,len);
	cout<<endl;

	cout<<"PostTravel: ";
	Post(arr,len);
	cout<<endl;
	return 0;
}


發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章