【数据结构】(十三)二叉树遍历的非递归算法,以及C++Stack容器的用法

二叉树遍历的非递归算法

(一)前序遍历的非递归算法:
【数据结构】(十三)二叉树遍历的非递归算法,以及C++Stack容器的用法_第1张图片
【数据结构】(十三)二叉树遍历的非递归算法,以及C++Stack容器的用法_第2张图片
动画演示4:08
【数据结构】(十三)二叉树遍历的非递归算法,以及C++Stack容器的用法_第3张图片
【数据结构】(十三)二叉树遍历的非递归算法,以及C++Stack容器的用法_第4张图片
【数据结构】(十三)二叉树遍历的非递归算法,以及C++Stack容器的用法_第5张图片
【数据结构】(十三)二叉树遍历的非递归算法,以及C++Stack容器的用法_第6张图片


         //***********————《方法一:利用类创建栈的写法(推荐方法二)》————*********//
#include 
using namespace std;
#include

struct Node
{
	char dat;
	struct Node* lchild;
	struct Node* rchild;
	int ltag;
	int rtag;
	Node* next;
};

struct Box
{
	char date;
	struct Node* lchild;
	struct Node* rchild;
	int ltag;
	int rtag;
	Box *next;
};

class  Stacket     //栈的建立,用来存储以遇到字母
{
public:
	Box* top;
	Box* base;
	void Initzhan(Stacket* s)
	{
		s->top = new Box;
		if (s->top == NULL)
			return;
		else
		{
			s->base = s->top;
			s->top->next = NULL;
		}
		return;
	}

	void push(Stacket* s,Node *temp)
	{
		Box p ;
		//***赋值***//
		p.date = temp->dat;
		p.lchild = temp->lchild;
		p.rchild = temp->rchild;
		p.ltag = temp->ltag;
		p.rtag = temp->rtag;
		//***赋值***//
		p.next=s->top;
		s->top = &p;
	}

	void pop(Stacket* s, Node &temp)
	{
		if (s->empty(s) == true)
		{
			return;
		}
		else
		{
			Box p = *s->top;
			temp.dat = p.date;
			temp.lchild = p.lchild;
			temp.rchild = p.rchild;
			temp.ltag = p.ltag;
			temp.rtag = p.rtag;
			s->top--;
			delete(&p);
		}
		
	}

	bool empty(Stacket* s)
	{
		if (s->top == s->base)
		{
			return true;
		}
		else
			return false;
	}
};

void Creat(char ch[],Node *&root)      //二叉树的创建
{
	static int i = 0;
	if (ch[i] == '#')
	{
		root = NULL;
	}
	else
	{
		root = new Node;     
		root->dat = ch[i];
		i++;
		Creat(ch,root->lchild);
		Creat(ch,root->rchild);
	}
}

void Show(Node *root,Stacket* s)  //前序遍历(非递归算法)
{
	Node *temp ;
	temp = root;
	while (temp != NULL || s->empty(s)==false)
	{
		while (temp != NULL)//当p为空,栈也为空的时候退出循环
		{
			cout << temp->dat << endl;  //访问根节点
			s->push(s,temp);   //将根结点压入栈中
			temp = temp->lchild;  //遍历右子树
		}
		//当发现一个根的左子树为空,那么弹出栈顶元素,走其右子树
		if (s->empty(s) != false)
		{
			s->pop(s, *temp);
			temp = temp->rchild;
		}
	}
}


int main()
{
	Node* root = NULL;
	Stacket s;
	char ch[11] = "ABC#D##C##";
	s.Initzhan(&s);   //初始化栈
	Creat(ch,*&root);
	Show(*&root,&s);
	system("pause");
	return 0;
}

              //*********----《 方法二: C++的stack容器栈的写法 》----*************//
#include
using namespace std;
#include
struct node
{
	char data;
	node* lchild;
	node* rchild;
};
//树的建立---前序建立
void creatTree(char ch[10], node*& root)
{
	static int i = 0;
	if (ch[i] == '#')
	{
		i++;
		root = NULL;
		return;
	}
	else
	{
		root = new node;
		root->data = ch[i];
		i++;
		creatTree(ch, root->lchild);
		creatTree(ch, root->rchild);
	}
}
//非递归遍历
void display(node* root)
{
	stack<node*> s;
	node* p = root;
	//当p为空,栈也为空的时候退出循环
	while (p != NULL || !s.empty())
	{
		while (p != NULL)
		{
			cout << p->data << endl;
			s.push(p);
			p = p->lchild;
		}
		//当发现一个根的左子树为空,那么弹出栈顶元素,走其右子树
		if (!s.empty())
		{
			p = s.top();
			s.pop();
			p = p->rchild;
		}
	}
}
//测试---------------------
void test()
{
	node* root = NULL;
	char ch[10] = "AB#D##C##";
	creatTree(ch, root);
	display(root);
}
int main()
{
	test();
	system("pause");
	return 0;
}

【数据结构】(十三)二叉树遍历的非递归算法,以及C++Stack容器的用法_第7张图片

(二)中序遍历(只不过改了输出的位置,其他不变):
将输出改在POP弹出栈的位置,意思就是所弹出栈的结点即为输出结点。
【数据结构】(十三)二叉树遍历的非递归算法,以及C++Stack容器的用法_第8张图片
【数据结构】(十三)二叉树遍历的非递归算法,以及C++Stack容器的用法_第9张图片

![在这里插入代码片

(三)后序遍历的非递归算法:
【数据结构】(十三)二叉树遍历的非递归算法,以及C++Stack容器的用法_第10张图片
【数据结构】(十三)二叉树遍历的非递归算法,以及C++Stack容器的用法_第11张图片

(四)。C++中Stack容器的用法:
一、stack的定义:C++stack(堆栈)是一个容器的改编,它实现了一个先进后出的数据结构(FILO),不允许被遍历,没有迭代器。 使用该容器时需要包含#include头文件;

定义stack对象的示例代码如下:

stacks1;
stacks2;

二、stack的基本操作有:

1.入栈:如s.push(x);
2.出栈:如 s.pop().注意:出栈操作只是删除栈顶的元素,并不返回该元素。
3.访问栈顶:如s.top();
4.判断栈空:如s.empty().当栈空时返回true。
5.访问栈中的元素个数,如s.size();

如下为一个简单的例子:

#include
#include     //使用stack文件需包含该头文件
using namespace std;
int main(void)
{
	stack<double>s;//定义一个栈
	for(int i=0;i<10;i++)
		s.push(i);
	while(!s.empty())
	{
		printf("%lf\n",s.top());
		s.pop();
	}
	cout<<"栈内的元素的个数为:"<<s.size()<<endl;
	return 0;
}

三、stack对象的默认构造
stack采用模板类实现, stack对象的默认构造形式: stack stkT;

stack <int> stkInt;            //一个存放int的stack容器。

stack <float> stkFloat;     //一个存放float的stack容器。

stack <string> stkString;     //一个存放string的stack容器。

PS:尖括号内还可以设置指针类型或自定义类型。

四、stack的push()与pop()方法

      stack.push(elem);   //往栈头添加元素

   stack.pop();   //从栈头移除第一个元素 

stack<int> stkInt;  
stkInt.push(1);stkInt.push(3);stkInt.pop();   
stkInt.push(5);stkInt.push(7);  
stkInt.push(9);stkInt.pop();   
stkInt.pop();  
此时stkInt存放的元素是1,5  

五、stack对象的拷贝构造与赋值

stack(const stack &stk);      //拷贝构造函数

stack& operator=(const stack &stk); //重载等号操作符

 

stack<int> stkIntA;

stkIntA.push(1);

stkIntA.push(3);

stkIntA.push(5);

stkIntA.push(7);

stkIntA.push(9);

 

stack<int> stkIntB(stkIntA); //拷贝构造

stack<int> stkIntC;

stkIntC = stkIntA; //赋值

六、stack的数据存取

stack.top();   //返回最后一个压入栈元素

stack<int> stkIntA;

stkIntA.push(1);

stkIntA.push(3);

stkIntA.push(5);

stkIntA.push(7);

stkIntA.push(9);

 

int iTop = stkIntA.top(); //9

stkIntA.top() = 19; //19

七、stack的大小

stack.empty();   //判断堆栈是否为空

stack.size();      //返回堆栈的大小

 

stack<int> stkIntA;

stkIntA.push(1);

stkIntA.push(3);

stkIntA.push(5);

stkIntA.push(7);

stkIntA.push(9);

 

if (!stkIntA.empty())

{
int iSize = stkIntA.size(); //5

}

对stack的说明

有关stack的代码


template<class T>
class stackNode
{
    public:
    stackNode():next(NULL){}
    T data;//值
    stackNode* next;//指向下一个节点的指针
};
template<class T>
class mystack
{
    private:
    unsigned int stacklength;
    stackNode<T>* node;//临时节点
    stackNode<T>* headnode;//尾结点
    public:
        mystack();//初始化
        unsigned int length();//栈元素的个数
        void push(T x);//入栈
        bool isEmpty();//判断栈是否为空
        void pop();//出栈
        T top();//获得栈顶元素
        void clear();//清空栈
 
};
template<class T>
mystack<T>::mystack()
{
    node=NULL;
    headnode=NULL;
    stacklength=0;
}
template<class T>
inline unsigned int mystack<T>::length(){return stacklength;}
template<class T>
void  mystack<T>::push(T x)
{
    node=new stackNode<T>();
    node->data=x;
    node->next=headnode;//把node变成头节点
    headnode=node;
    ++stacklength;
}
template<class T>
bool  mystack<T>::isEmpty()
{
    return stacklength==0;
}
template<class T>
void  mystack<T>::pop()
{
    if(isEmpty()) return;
    node=headnode;
    headnode=headnode->next;//头节点变成它的下一个节点
    delete(node);//删除头节点
    --stacklength;
}
template<class T>
T  mystack<T>::top()
{
    if(!isEmpty())
    return headnode->data;
}
template<class T>
void  mystack<T>::clear()
{
    while(headnode!=NULL)
    {
        node=headnode;
        headnode=headnode->next;
        delete(node);
    }
    node=NULL;
    headnode=NULL;
    stacklength=0;
}


你可能感兴趣的:(数据结构,二叉树的非递归遍历,C++的stack容器,算法,数据结构,二叉树)