1. 程式人生 > >資料結構 : 二叉樹的遍歷

資料結構 : 二叉樹的遍歷

資料結構 : 二叉樹的遍歷

遞迴的遍歷就不寫了

下面都是利用迭代的遍歷方法

前序遍歷

  • 利用一個棧
void NormalBinaryTree::preOrder() {
	std::cout << "先序遍歷: 非遞迴 " << std::endl;
	preOrderHelper(root);
	std::cout << std::endl;
}

void NormalBinaryTree::preOrderHelper(TreeNode* root) {
	stack<TreeNode*> s;
	TreeNode* p = root;

	while (!s.empty() || p != NULL) {
		// 一直向下搜尋,入棧
		while (p != NULL) {
			std::cout << p->val << std::ends;
			s.push(p);
			p = p->left;
		}
		if (!s.empty()) {
			p = s.top(); s.pop();
			p = p->right;
		}
	}
}

中序遍歷

  • 利用一個棧,和前序遍歷結構一樣.
  • 只是列印的位置不同
void NormalBinaryTree::inOrder() {
	std::cout << "中序遍歷: 非遞迴 " << std::endl;
	inOrderHelper(root);
	std::cout << std::endl;
}
void NormalBinaryTree::inOrderHelper(TreeNode* root) {

	stack<TreeNode*> s;
	TreeNode* p = root;

	while (!s.empty() || p != NULL) {
		// 一直向左下下搜尋,入棧
		while (p != NULL) {
			s.push(p);
			p = p->left;
		}

		if (!s.empty()) {
			p = s.top(); s.pop();
			std::cout << p->val << std::ends;
			p = p->right;
		}
	}
}

後序遍歷

  • 後序遍歷看起來比較難
  • 非遞迴的有兩個版本:

利用兩個棧

void NormalBinaryTree::postOrderHelper(TreeNode* root) {

	// 方法1:利用兩個棧實現
	stack<TreeNode*> s1;
	stack<TreeNode*> s2;

	TreeNode* p = root;

	while (p != NULL || !s1.empty()) {
		while (p != NULL) {
			s1.push(p);
			s2.push(p);
			p = p->right;
		}
		p = s1.top();
		s1.pop();
		p = p->left;
	}

	while (!s2.empty()) {
		std::cout << s2.top()->val << std::ends;
		s2.pop();
	}
}

利用一個棧

void NormalBinaryTree::postOrderHelper2(TreeNode* root) {

    // 方法2:利用一個棧實現
    stack<TreeNode*> s1;
    s1.push(root);

    TreeNode* h = root;
    TreeNode* p = NULL;

    while (!s1.empty()) {
        p = s1.top();
        if (p->left != NULL&&h != p->left&&h != p->right) {
            s1.push(p->left);
        }
        else if (p->right != NULL&&h != p->right) {
            s1.push(p->right);
        }
        else {
            std::cout << p->val << ends;
            s1.pop();
            h = p;
        }
    }
}

層次遍歷

// 層序遍歷
void NormalBinaryTree::levelOrder() {
	std::cout << "層序遍歷:" << std::endl;

	TreeNode* cur = root;
	queue<TreeNode*> q;
	q.push(cur);

	int tobeprint = 1;
	int level = 1;
	int nextLevel = 0;

	while (!q.empty()) {
		cur = q.front();
		q.pop();
		std::cout << cur->val << std::ends;
		tobeprint--;
		if (cur->left != NULL) {
			q.push(cur->left);
			nextLevel++;
		}
		if (cur->right != NULL) {
			q.push(cur->right);
			nextLevel++;
		}
		
		if (tobeprint == 0) {
			tobeprint = nextLevel;
			nextLevel = 0;
			level++;
			std::cout << endl;
		}
	}
}

參考文獻

二叉樹的前中後序遍歷,遞迴和非遞迴方式

二叉樹七種遍歷方式