1. 程式人生 > 實用技巧 >二叉樹遍歷演算法遞迴實現+層次遍歷

二叉樹遍歷演算法遞迴實現+層次遍歷

二叉樹遍歷演算法

二叉樹的儲存結構

typedef struct BTNode
{
    char data;				//這裡預設結點data為char型
    struct BTNode *lchild;
    struct BTNode *rchild;
}BTNode;

二叉樹的遍歷演算法

1 先序遍歷

先序遍歷的操作如下。

如果二叉樹為空樹,則什麼都不做;否則:

1)訪問根節點

2)先序遍歷左子樹

3)先序遍歷右子樹

描述如下:

void preorder(BTNode *p)
{
	if(p != NULL)
    {
		visit(p);				//假設訪問函式Visit()已經定義過
        preorder(p->lchild);	//先序遍歷左子樹
        preorder(p->rchild);	//先序遍歷右子樹
    }
}

2 中序遍歷

中序遍歷的操作如下。

如果二叉樹為空樹,則什麼都不做;否則:

1)中序遍歷左子樹

2)訪問根節點

3)中序遍歷右子樹

描述如下:

void inorder(BTNode *p)
{
	if(p != NULL)
    {
        inorder(p->lchild);
        visit(p);
        inorder(p->rchild);
    }
}

3 後序遍歷

後序遍歷的操作如下。

如果二叉樹為空樹,則什麼都不做;否則:

1)後序遍歷左子樹

2)後序遍歷右子樹

3)訪問根節點

描述如下:

void postorder(BTNode *p)
{
	if(p != NULL)
    {
        postorder(p->lchild);
        postorder(p->rchild);
        visit(p);
    }
}

4 層次遍歷

上圖所示為二叉樹的層次遍歷,即按照箭頭所指方向,按照1、2、3、4的層次順序,對二叉樹中各個結點進行訪問(此圖反映的是自左至右的層次遍歷,自右至左的方式類似)
要進行層次遍歷,需要建立一個迴圈佇列先將二叉樹頭結點入佇列,然後出佇列,訪問該結點,如果它有左子樹,則將左子樹的根結點入隊;如果它有右子樹,則將右子樹的根結點入隊。然後出佇列,對出隊結點訪問。如此反覆,直到佇列為空為止。
由此得到的對應演算法如下:

void level(BTNode *p)
{
	int  front,rear;
    BTNode *que[maxSize];		//定義一個迴圈佇列,用來記錄將要訪問的層次上的結點
    front = rear = 0;
    BTNode *q;
    if(p != NULL)
    {
        rear = (rear + 1) % maxSize;
        que[rear] = p;					//根結點入隊
        while(front != rear)			//當佇列不空的時候進行迴圈
        {
            front = (front + 1) % maxSize;
            q = que[front];				//隊頭結點出隊
            visit(q);					//訪問隊頭結點
            if(q->lchild != NULL)		//如果左子樹不空,則左子樹的根結點入隊
            {
                rear = (rear + 1) % maxSize;
                que[rear] = q->lchild;
			}
            if(q->rchild != NULL)		//如果右子樹不空,則右子樹的根結點入隊
            {
                rear = (rear + 1) % maxSize;
                que[rear] = q->rchild;
			}
        }
    }
}