二叉樹的存儲:
1、順序存儲:
對於一般的二叉樹,添加一些空結點,使之成爲完全二叉樹。按照完全二叉樹層序編號,把結點依次存儲在一維數組中。把空結點設置爲“^”。
2、二叉鏈表:
二叉樹樹每個結點最多有兩個孩子,所以爲它設計一個數據域和兩個指針域的鏈式存儲結構,我們稱這樣的鏈表叫做二叉鏈表。其中data是數據域,lchild和rchild都是指針域,分別存放指向左孩子和右孩子的指針。
typedef struct BiTNode
{
TElemType data;
struct BiTNode *lchild, *rchild;
} BiTNode, *BiTree;
遍歷二叉樹
二叉樹的遍歷是指從根結點出發,按照某種次序依次訪問二叉樹中所有結點,使得每個結點都被訪問一次且僅被訪問一次。
1、前序遍歷:若二叉樹爲空,則空操作返回,否則先訪問根結點,然後前序遍歷左子樹,再前序遍歷右子樹。
2、中序遍歷:若二叉樹爲空,則空操作返回,否則從根結點開始(注意並不是先訪問根結點),中序遍歷根結點的左子樹,然後是訪問根結點,最後中序遍歷右子樹。
3、後序遍歷:若二叉樹爲空,則空操作返回,否則從左到右先葉子後結點的方式遍歷訪問左右子樹,最後是訪問根結點。
4、層序遍歷:若二叉樹爲空,則空操作返回,否則從樹的第一層,也就是根結點開始訪問,從上而下逐層遍歷,在同一層中,按從左到右的順序對結點逐個訪問。
前序遍歷算法:
void PreOrderTraverse(BiTree T)
{
if (T == NULL)
return;
printf("%c", T->data);
PreOrderTraverse(T->lchild);
PreOrderTraverse(T->rchild);
}
中序遍歷算法:
void InOrderTraverse(BiTree T)
{
if (T == NULL)
return;
InOrderTraverse(T->lchild);
printf("%c", T->data);
InOrderTraverse(T->rchild);
}
後序遍歷算法:
void PostOrderTraverse(BiTree T)
{
if (T == NULL)
return;
PostOrderTraverse(T->lchild);
PostOrderTraverse(T->rchild);
printf("%c", T->data);
}
1、已知前序遍歷和中序遍歷序列,可以唯一確定一棵二叉樹。
2、已知後序遍歷和中序遍歷序列,可以唯一確定一棵二叉樹。
已知前序和後序遍歷序列,是不能確定一棵二叉樹的。
二叉樹的建立:
爲了能讓每個結點確認是否有左右孩子,我們對它進行了擴展,也就是將二叉樹中每個結點的空指針引出一個虛結點,其值爲一特定值,比如“#”。我們稱這種處理後的二叉樹爲原二叉樹的擴展二叉樹。擴展二叉樹就可以做到一個遍歷序列確定一棵二叉樹。
由擴展二叉樹的前序遍歷序列生成一棵二叉樹:
void CreateBiTree(BiTree *T)
{
TElemType ch;
scanf("%c", &ch);
if (ch == '#')
*T = NULL;
else
{
*T = (BiTree)malloc(sizeof(BiTNode));
(*T)->data = ch;
if (!*T)
exit(OVERFLOW);
CreateBiTree(&(*T)->lchild);
CreateBiTree(&(*T)->rchild);
}
}