樹結構是一種描述非線性關係的數據結構。對於樹的基本概念不想過多贅述,可以自行查閱相關資料,這裏主要講解一種簡單的樹結構——二叉樹。二叉樹是樹的一種特殊形式,它有n個結點,每個結點最多有兩個子結點。二叉樹的子樹仍然是二叉樹,二叉樹的兩個子樹分別是左子樹和右子樹,因此二叉樹也是有序樹。二叉樹又分爲:完全二叉樹和滿二叉樹,概念不再詳述,自行查找。
完全二叉樹的性質:
1、如果m!=1,則結點m的父節點爲m/2;
2、如果2*m<=n,則m的左子樹編號爲2*m;若2*m>n則無左子樹,也無右子樹。
3、如果2*m+1<=n,則m的右子樹編號爲2*m+1;若2*m+1>n則無右子樹。
完全二叉樹的深度爲[log2n]+1。
二叉樹的存儲方式:1、順序存儲 2、鏈式存儲。
順序存儲即按層將二叉樹存儲到一個數組中,這裏不再詳述,重點講鏈式存儲。
二叉樹的鏈式存儲:
1、數據部分
class CBTType //定義二叉樹結點類型
{
String data; //元素數據
CBTType left; //左子樹結點指針
CBTType right; //右子樹結點指針
}
2、初始化二叉樹
CBTType InitTree() //初始化二叉樹的根
{
CBTType node;
if((node=new CBTType())!=null) //申請內存
{
System.out.printf("請先輸入一個根結點數據:\n");
node.data=input.next();
node.left=null;
node.right=null;
if(node!=null) //如果二叉樹根結點不爲空
{
return node;
}
else
{
return null;
}
}
return null;
}
3、添加結點
void AddTreeNode(CBTType treeNode) //添加結點
{
CBTType pnode,parent;
String data;
int menusel;
if((pnode=new CBTType())!=null) //分配內存
{
System.out.printf("輸入二叉樹結點數據:\n");
pnode.data=input.next();
pnode.left=null; //設置左右子樹爲空
pnode.right=null;
System.out.printf("輸入該結點的父結點數據:");
data=input.next();
parent=TreeFindNode(treeNode,data); //查找指定數據的結點
if(parent==null) //如果未找到
{
System.out.printf("未找到該父結點!\n");
pnode=null; //釋放創建的結點內存
return;
}
System.out.printf("1.添加該結點到左子樹\n2.添加該結點到右子樹\n");
do
{
menusel=input.nextInt(); //輸入選擇項
if(menusel==1 || menusel==2)
{
if(parent==null)
{
System.out.printf("不存在父結點,請先設置父結點!\n");
}
else
{
switch(menusel)
{
case 1: //添加到左結點
if(parent.left!=null) //左子樹不爲空
{
System.out.printf("左子樹結點不爲空!\n");
}
else
{
parent.left=pnode;
}
break;
case 2: //添加到右結點
if( parent.right!=null) //右子樹不爲空
{
System.out.printf("右子樹結點不爲空!\n");
}
else
{
parent.right=pnode;
}
break;
default:
System.out.printf("無效參數!\n");
}
}
}
}while(menusel!=1 && menusel!=2);
}
}
4、查找結點
CBTType TreeFindNode(CBTType treeNode,String data) //查找結點
{
CBTType ptr;
if(treeNode==NULL)
{
return NULL;
}
else
{
if(treeNode.data.equals(data))
{
return treeNode;
}
else //查找左右子樹
{
if((ptr=TreeFindNode(treeNode.left,data))!=NULL)
{
return ptr;
}
else if((ptr=TreeFindNode(treeNode.left,data))!=NULL)
{
return ptr;
}
else
{
return null;
}
}
}
}
5、獲取左/右子樹
CBTType TreeLeftNode(CBTType treeNode) //獲取左子樹
{
if(treeNode!=null)
{
return treeNode.left; //返回值
}
else
{
return null;
}
}
CBTType TreeRightNode(CBTType treeNode) //獲取右子樹
{
if(treeNode!=null)
{
return treeNode.right; //返回值
}
else
{
return null;
}
}
6、判斷樹是否爲空 計算二叉樹深度
int TreeIsEmpty(CBTType treeNode) //判斷空樹
{
if(treeNode!=null)
{
return 0;
}
else
{
return 1;
}
}
int TreeDepth(CBTType treeNode) //計算二叉樹深度
{
int depleft,depright;
if(treeNode==null)
{
return 0; //對於空樹,深度爲0
}
else
{
depleft = TreeDepth(treeNode.left); //左子樹深度 (遞歸調用)
depright = TreeDepth(treeNode.right); //右子樹深度 (遞歸調用)
if(depleft>depright)
{
return depleft + 1;
}
else
{
return depright + 1;
}
}
}
7、清空二叉樹 顯示結點數據
void ClearTree(CBTType treeNode) // 清空二叉樹
{
if(treeNode!=null)
{
ClearTree(treeNode.left); //清空左子樹
ClearTree(treeNode.right); //清空右子樹
treeNode=null; //釋放當前結點所佔內存
// treeNode=null;
}
}
void TreeNodeData(CBTType p) //顯示結點數據
{
System.out.printf("%s ",p.data); //輸出結點數據
}
8、二叉樹遍歷算法
(1)按層遍歷算法
void LevelTree(CBTType treeNode) //按層遍歷
{
CBTType p;
CBTType[] q=new CBTType[MAXLEN]; //定義一個順序棧
int head=0,tail=0;
if(treeNode!=null) //如果隊首指針不爲空
{
tail=(tail+1)%MAXLEN; //計算循環隊列隊尾序號
q[tail] = treeNode; //將二叉樹根指針進隊
}
while(head!=tail) //隊列不爲空,進行循環
{
head=(head+1)%MAXLEN; //計算循環隊列的隊首序號
p=q[head]; //獲取隊首元素
TreeNodeData(p); //處理隊首元素
if(p.left!=null) //如果結點存在左子樹
{
tail=(tail+1)%MAXLEN; //計算循環隊列的隊尾序號
q[tail]=p.left; //將左子樹指針進隊
}
if(p.right!=null) //如果結點存在右子樹
{
tail=(tail+1)%MAXLEN; //計算循環隊列的隊尾序號
q[tail]=p.right; //將右子樹指針進隊
}
}
}
(2)先序遍歷
void DLRTree(CBTType treeNode) //先序遍歷
{
if(treeNode!=null)
{
TreeNodeData(treeNode); //顯示結點的數據
DLRTree(treeNode.left);
DLRTree(treeNode.right);
}
}
(3)中序遍歷
void LDRTree(CBTType treeNode) //中序遍歷
{
if(treeNode!=null)
{
LDRTree(treeNode.left); //中序遍歷左子樹
TreeNodeData(treeNode); //顯示結點數據
LDRTree(treeNode.right); //中序遍歷右子樹
}
}
(4)後序遍歷
void LRDTree(CBTType treeNode) //後序遍歷
{
if(treeNode!=null)
{
LRDTree(treeNode.left); //後序遍歷左子樹
LRDTree(treeNode.right); //後序遍歷右子樹
TreeNodeData(treeNode); //顯示結點數據
}
}
到此爲止,樹的基本數據結構就到此結束了!