1. 程式人生 > >陣列形式二叉樹之C++封裝

陣列形式二叉樹之C++封裝

一、陣列與二叉樹的對應關係如下:

                                                                                                                              

說明:節點在陣列中的位置對應它在樹中的位置,下標為0 的節點為根節點,下標為1是根的左節點,2為根節點的右節點,依次類推,從左到右的順序儲存樹的每一層。

      假設某一節點的索引是 n ,則:

      其左子節點的索引 = n * 2 + 1;

      其右子節點的索引 = n * 2 + 2;

      其父節點的索引 = (n - 1)/ 2;

陣列形式二叉樹的主要操作有:

      1、樹的建立和銷燬

      2、樹中節點的搜尋

      3、樹中節點的新增和刪除

      4、樹中節點的遍歷

二、封裝

.h檔案:

#pragma once
class CZzcArrayTree
{
public:
	CZzcArrayTree(int nSize,int* pTreeRoot);//建立樹:樹節點的多少;根節點
	~CZzcArrayTree();//銷燬樹
	int* SearchNode(int NodeIndex);//搜尋節點
	bool AddNode(int NodeIndex,int Direction,int* pNode);//增加節點的父節點;增加為左節點或右節點;要增加的節點
	bool DeleteNode(int NodeIndex,int* pNode);//刪除節點索引;輸出刪除的節點
	void TraverseTree();//遍歷樹
	void TraverseDel(int NodeIndex);//遍歷刪除一個節點的所有子節點
private:
	int* m_pTree;
	int m_nSize;
};

.Cpp檔案:

#include "StdAfx.h"
#include "ZzcArrayTree.h"
#include <iostream>
using namespace std;



CZzcArrayTree::CZzcArrayTree(int nSize,int* pTreeRoot)
{
	m_nSize = nSize;
	m_pTree = new int[m_nSize];

	m_pTree[0] = *pTreeRoot;

	for (int i = 1;i < m_nSize;i++)
	{
		m_pTree[i] = 0;
	}
}


CZzcArrayTree::~CZzcArrayTree()
{
	if (m_pTree)
	{
		delete[] m_pTree;
		m_pTree = NULL;
	}
}

int* CZzcArrayTree::SearchNode(int NodeIndex)
{
	if(NodeIndex < 0||NodeIndex >= m_nSize) return NULL;//索引值超範圍

	if(m_pTree[NodeIndex] == 0) return NULL;        //空節點

	return &m_pTree[NodeIndex];
}

bool CZzcArrayTree::AddNode(int NodeIndex,int Direction,int* pNode)
{
	if(NodeIndex < 0||NodeIndex >= m_nSize) return false;//索引值超範圍

	if(m_pTree[NodeIndex] == 0) return false;        //空節點不能新增子節點

	if (Direction == 0)//新增為左節點
	{
		int  LeftChildIndex = NodeIndex * 2 + 1;

		if(LeftChildIndex >= m_nSize) return false;//超出範圍

		if(m_pTree[LeftChildIndex] != 0) return false;//左節點已經有值

		m_pTree[LeftChildIndex] = *pNode;
	} 
	else//新增為右節點
	{
		int RightChildIndex = NodeIndex * 2 + 2;

		if(RightChildIndex >= m_nSize) return false;//超出範圍

		if(m_pTree[RightChildIndex] != 0) return false;//右節點已經有值

		m_pTree[RightChildIndex] = *pNode;
	}

	return true;
}

bool CZzcArrayTree::DeleteNode(int NodeIndex,int* pNode)
{
	if(NodeIndex < 0||NodeIndex >= m_nSize) return false;//索引值超範圍

	if(m_pTree[NodeIndex] == 0) return false;        //空節點不能刪除

	*pNode = m_pTree[NodeIndex];

	m_pTree[NodeIndex] = 0;

	TraverseDel(NodeIndex);

	return true;
}

void CZzcArrayTree::TraverseTree()
{
	for (int i= 0;i < m_nSize;i++)
	{
		cout<<m_pTree[i]<<" ";
	}
	cout<<endl;
}

void CZzcArrayTree::TraverseDel(int NodeIndex)
{
	if (NodeIndex < 0|| NodeIndex >= m_nSize) return;

	if (NodeIndex * 2 + 1 < m_nSize)//左子節點符合
	{
		m_pTree[NodeIndex * 2 + 1] = 0;

		TraverseDel( NodeIndex * 2 + 1);
	}
	
	if (NodeIndex * 2 + 2 < m_nSize)//右子節點符合
	{
		m_pTree[NodeIndex * 2 + 2] = 0;

		TraverseDel( NodeIndex * 2 + 2);
	}
}