乡下人产国偷v产偷v自拍,国产午夜片在线观看,婷婷成人亚洲综合国产麻豆,久久综合给合久久狠狠狠9

  • <output id="e9wm2"></output>
    <s id="e9wm2"><nobr id="e9wm2"><ins id="e9wm2"></ins></nobr></s>

    • 分享

      二叉樹先序、中序、后序遍歷的非遞歸實現(xiàn)

       勤奮不止 2012-05-10

      二叉樹先序、中序、后序遍歷的非遞歸實現(xiàn)

      在網(wǎng)上看了一些用非遞歸實現(xiàn)先序中序后序遍歷二叉樹的代碼,都很混亂,while、if各種組合嵌套使用,邏輯十分不清晰,把我也搞懵了。想了大半天,寫了大半天,突然開了竅,實際上二叉樹的這三種遍歷在邏輯上是十分清晰的,所以才可以用遞歸實現(xiàn)的那么簡潔。既然邏輯如此清晰,那么用非遞歸實現(xiàn)也應(yīng)該是清晰的。

      自認(rèn)為自己的代碼比網(wǎng)上搜到的那些都清晰得多,好理解得多。

      稍微解釋一下:

      先序遍歷。將根節(jié)點入棧,考察當(dāng)前節(jié)點(即棧頂節(jié)點),先訪問當(dāng)前節(jié)點,然后將其出棧(已經(jīng)訪問過,不再需要保留),然后先將其右孩子入棧,再將其左孩子入棧(這個順序是為了讓左孩子位于右孩子上面,以便左孩子的訪問先于右孩子;當(dāng)然如果某個孩子為空,就不用入棧了)。如果棧非空就重復(fù)上述過程直到??諡橹梗Y(jié)束算法。

      中序遍歷。將根節(jié)點入棧,考察當(dāng)前節(jié)點(即棧頂節(jié)點),如果其左孩子未被訪問過(有標(biāo)記),則將其左孩子入棧,否則訪問當(dāng)前節(jié)點并將其出棧,再將右孩子入棧。如果棧非空就重復(fù)上述過程直到??諡橹梗Y(jié)束算法。

      后序遍歷。將根節(jié)點入棧,考察當(dāng)前節(jié)點(即棧頂節(jié)點),如果其左孩子未被訪問過,則將其左孩子入棧,否則如果其右孩子未被訪問過,則將其右孩子入棧,如果都已經(jīng)訪問過,則訪問其自身,并將其出棧。如果棧非空就重復(fù)上述過程直到??諡橹?,結(jié)束算法。

      其實,這只不過是保證了先序中序后序三種遍歷的定義。對于先序,保證任意一個節(jié)點先于其左右孩子被訪問,還要保證其左孩子先于右孩子被訪問。對于中序,保證任意一個節(jié)點,其左孩子先于它被訪問,右孩子晚于它被訪問。對于后序,保證任意一個節(jié)點的左孩子右孩子都先于它被訪問,其中左孩子先于右孩子被訪問。如是而已。

      代碼里應(yīng)該體現(xiàn)得比較清楚。這里不光給出了非遞歸版本,也給出了遞歸版本。

      #include <iostream>
      #include <stack>
       
      using namespace std;
       
      struct TreeNode 
      {
      	int data;
      	TreeNode* left;
      	TreeNode* right;
      	int flag;
      };
       
      typedef TreeNode *TreePtr;
       
      TreePtr CreateTree()
      {
      	TreePtr root = new TreeNode;
      	cout<<"input the data :\n";
      	int n;
      	cin>>n;
      	if (n == -1)
      	{
      		return NULL;
      	} 
      	else
      	{
      		root->data = n;
      		root->flag = 0;
      		root->left = CreateTree();
      		root->right = CreateTree();
      	}
      	return root;
      }
       
      void PreOrderRecursion(TreePtr p)
      {
      	if (p == NULL)
      	{
      		return;
      	}
      	cout<<p->data<<" ";
      	PreOrderRecursion(p->left);
      	PreOrderRecursion(p->right);
      }
       
      void InOrderRecursion(TreePtr p)
      {
      	if (p == NULL)
      	{
      		return;
      	}
      	InOrderRecursion(p->left);
      	cout<<p->data<<" ";
      	InOrderRecursion(p->right);
      }
       
      void PostOrderRecursion(TreePtr p)
      {
      	if (p == NULL)
      	{
      		return;
      	}
      	PostOrderRecursion(p->left);
      	PostOrderRecursion(p->right);
      	cout<<p->data<<" ";
      }
       
      void PreOrderNoRecursion(TreePtr p)
      {
      	cout<<"PreOrderNoRecursion\n";
       
      	stack<TreeNode> stk;
      	TreeNode t = *p;
      	stk.push(t);
       
      	while (!stk.empty())
      	{
      		t = stk.top();
      		stk.pop();
      		cout<<t.data<<" ";
       
      		if (t.right != NULL)
      		{
      			stk.push((*t.right));
      		}
       
      		if (t.left != NULL)
      		{
      			stk.push((*t.left));
      		}
      	}
      }
       
      void InOrderNoRecursion(TreePtr p)
      {
      	cout<<"InOrderNoRecursion\n";
       
      	stack<TreeNode> stk;
      	TreeNode t = *p;
      	stk.push(t);
       
      	while (!stk.empty())
      	{
      		if (stk.top().flag == 0)
      		{
      			stk.top().flag++;
      			if (stk.top().left != NULL)
      			{
      				stk.push(*(stk.top().left));
      			}
      		}
      		else
      		{
      			t = stk.top();
      			stk.pop();
      			cout<<t.data<<" ";
      			if (t.right != NULL)
      			{
      				stk.push(*(t.right));
      			}
      		}
      	}
      }
       
      void PostOrderNoRecursion(TreePtr p)
      {
      	cout<<"PostOrderNoRecursion\n";
       
      	stack<TreeNode> stk;
      	TreeNode t = *p;
      	stk.push(t);
       
      	while (!stk.empty())
      	{
      		if (stk.top().flag == 0)
      		{
      			stk.top().flag++;
      			if (stk.top().left != NULL)
      			{
      				stk.push(*(stk.top().left));
      			}
      		} 
      		else if (stk.top().flag == 1)
      		{
      			stk.top().flag++;
      			if (stk.top().right != NULL)
      			{
      				stk.push(*(stk.top().right));
      			}
      		} 
      		else
      		{
      			cout<<stk.top().data<<" ";
      			stk.pop();
      		}
      	}
      }
       
      int main()
      {
      	TreePtr t = CreateTree();
       
      	cout<<"PreOrderRecursion\n";
      	PreOrderRecursion(t);
      	cout<<"\n";
       
      	cout<<"InOrderRecursion\n";
      	InOrderRecursion(t);
      	cout<<"\n";
       
      	cout<<"PostOrderRecursion\n";
      	PostOrderRecursion(t);
      	cout<<"\n";
       
      	PreOrderNoRecursion(t);
      	cout<<"\n";
       
      	InOrderNoRecursion(t);
      	cout<<"\n";
       
      	PostOrderNoRecursion(t);
      	cout<<"\n";
      }

        本站是提供個人知識管理的網(wǎng)絡(luò)存儲空間,所有內(nèi)容均由用戶發(fā)布,不代表本站觀點。請注意甄別內(nèi)容中的聯(lián)系方式、誘導(dǎo)購買等信息,謹(jǐn)防詐騙。如發(fā)現(xiàn)有害或侵權(quán)內(nèi)容,請點擊一鍵舉報。
        轉(zhuǎn)藏 分享 獻(xiàn)花(0

        0條評論

        發(fā)表

        請遵守用戶 評論公約

        類似文章 更多