图的深度优先搜索法是树的先根遍历的推广,它的基本思想是:从图G的某个顶点v0出发,访问v0,然后选择一个与v0相邻且没被访问过的顶点vi访问,再从vi出发选择一个与vi相邻且未被访问的顶点vj进行访问,依次继续。如果当前被访问过的顶点的所有邻接顶点都已被访问,则退回到已被访问的顶点序列中最后一个拥有未被访问的相邻顶点的顶点w,从w出发按同样的方法向前遍历,直到图中所有顶点都被访问。
图的广度优先搜索是树的按层次遍历的推广,它的基本思想是:首先访问初始点vi,并将其标记为已访问过,接着访问vi的所有未被访问过的邻接点vi1,vi2, …, vi t,并均标记已访问过,然后再按照vi1,vi2, …, vi t的次序,访问每一个顶点的所有未被访问过的邻接点,并均标记为已访问过,依次类推,直到图中所有和初始点vi有路径相通的顶点都被访问过为止。
图的广度优先搜索是树的按层次遍历的推广,它的基本思想是:首先访问初始点vi,并将其标记为已访问过,接着访问vi的所有未被访问过的邻接点vi1,vi2, …, vi t,并均标记已访问过,然后再按照vi1,vi2, …, vi t的次序,访问每一个顶点的所有未被访问过的邻接点,并均标记为已访问过,依次类推,直到图中所有和初始点vi有路径相通的顶点都被访问过为止。
二叉树的深度优先遍历的非递归的通用做法是采用栈,广度优先遍历的非递归的通用做法是采用队列。
- #include <stdlib.h>
- #include <stdio.h>
- #include <math.h>
- /* 函数结果状态代码 */
- #define TRUE 1
- #define FALSE 0
- #define OK 1
- #define ERROR 0
- #define INFEASIBLE -1
- #define OVERFLOW 3
- #define MAXSIZE 100 /* 存储空间初始分配量 */
- typedef int Status; /* Status是函数的类型,其值是函数结果状态代码,如OK等 */
- typedef char ElemType;
- typedef struct BiTNode {
- ElemType data;
- struct BiTNode *lchild, *rchild; /* 左右孩子指针 */
- } BiTNode, *BiTree;
- /* 链栈结构 */
- typedef struct StackNode
- {
- BiTNode data;
- struct StackNode *next;
- }StackNode,*LinkStackPtr;
- typedef struct
- {
- LinkStackPtr top;
- int count;
- }LinkStack;
- /*队列结构*/
- typedef struct QNode {
- BiTNode data;
- struct QNode *next;
- } QNode, *QueuePtr;
- typedef struct {
- QueuePtr front, rear; /* 队头、队尾指针 */
- } LinkQueue;
- /* 链队列 的基本操作*/
- void InitQueue(LinkQueue *Q)
- {
- /* 构造一个空队列Q */
- (*Q).front = (*Q).rear = (QueuePtr)malloc(100*sizeof(QNode));
- if(!(*Q).front)
- exit(OVERFLOW);
- (*Q).front->next = NULL;
- }
- void DestroyQueue(LinkQueue *Q)
- {
- /* 销毁队列Q(无论空否均可) */
- while((*Q).front) {
- (*Q).rear = (*Q).front->next;
- free((*Q).front);
- (*Q).front = (*Q).rear;
- }
- }
- Status QueueEmpty(LinkQueue Q)
- {
- /* 若Q为空队列,则返回TRUE,否则返回FALSE */
- if(Q.front->next == NULL)
- return TRUE;
- else
- return FALSE;
- }
- Status GetHead_Q(LinkQueue Q, BiTNode *e) /* 避免与bo2-6.c重名 */
- {
- /* 若队列不空,则用e返回Q的队头元素,并返回OK,否则返回ERROR */
- QueuePtr p;
- if(Q.front == Q.rear)
- return ERROR;
- p = Q.front->next;
- *e = p->data;
- return OK;
- }
- void EnQueue(LinkQueue *Q, BiTNode e)
- {
- /* 插入元素e为Q的新的队尾元素 */
- QueuePtr p = (QueuePtr)malloc(sizeof(QNode));
- if(!p) /* 存储分配失败 */
- exit(OVERFLOW);
- p->data =e;
- p->next = NULL;
- (*Q).rear->next = p;
- (*Q).rear = p;
- }
- Status DeQueue(LinkQueue *Q, BiTNode *e)
- {
- /* 若队列不空,删除Q的队头元素,用e返回其值,并返回OK,否则返回ERROR */
- QueuePtr p;
- if((*Q).front == (*Q).rear)
- return ERROR;
- p = (*Q).front->next;
- *e = p->data;
- (*Q).front->next = p->next;
- if((*Q).rear == p)
- (*Q).rear = (*Q).front;
- free(p);
- return OK;
- }
- //#####################################################//
- /* 链栈的基本操作*/
- /* 构造一个空栈S */
- Status InitStack(LinkStack *S)
- {
- S->top = (LinkStackPtr)malloc(sizeof(StackNode));
- if(!S->top)
- return ERROR;
- S->top=NULL;
- S->count=0;
- return OK;
- }
- /* 把S置为空栈 */
- Status ClearStack(LinkStack *S)
- {
- LinkStackPtr p,q;
- p=S->top;
- while(p)
- {
- q=p;
- p=p->next;
- free(q);
- }
- S->count=0;
- return OK;
- }
- /* 若栈S为空栈,则返回TRUE,否则返回FALSE */
- Status StackEmpty(LinkStack S)
- {
- if (S.count==0)
- return TRUE;
- else
- return FALSE;
- }
- /* 返回S的元素个数,即栈的长度 */
- int StackLength(LinkStack S)
- {
- return S.count;
- }
- /* 若栈不空,则用e返回S的栈顶元素,并返回OK;否则返回ERROR */
- Status GetTop(LinkStack S, BiTNode *e)
- {
- if (S.top==NULL)
- return ERROR;
- else
- *e=S.top->data;
- return OK;
- }
- /* 插入元素e为新的栈顶元素 */
- Status Push(LinkStack *S, BiTNode e)
- {
- LinkStackPtr s=(LinkStackPtr)malloc(sizeof(StackNode));
- s->data=e;
- s->next=S->top; /* 把当前的栈顶元素赋值给新结点的直接后继*/
- S->top=s; /* 将新的结点s赋值给栈顶指针*/
- S->count++;
- return OK;
- }
- /* 若栈不空,则删除S的栈顶元素,用e返回其值,并返回OK;否则返回ERROR */
- Status Pop(LinkStack *S, BiTNode *e)
- {
- LinkStackPtr p;
- if(StackEmpty(*S))
- return ERROR;
- *e=S->top->data;
- p=S->top; /* 将栈顶结点赋值给p */
- S->top=S->top->next; /* 使得栈顶指针下移一位,指向后一结点*/
- free(p); /* 释放结点p */
- S->count--;
- return OK;
- }
- /* 用于构造二叉树********************************** */
- int count=1;
- typedef char String[100]; /* 0号单元存放串的长度 */
- String str;
- Status StrAssign(String T,char *chars)
- {
- int i;
- if(strlen(chars)>MAXSIZE)
- return ERROR;
- else
- {
- T[0]=strlen(chars);
- for(i=1;i<=T[0];i++)
- T[i]=*(chars+i-1);
- return OK;
- }
- }
- /* ************************************************ */
- void CreateBiTree(BiTree *T)
- {
- /* 按先序次序输入二叉树中结点的值(此处字符型)*/
- /* 构造二叉链表表示的二叉树T。 */
- ElemType ch;
- ch=str[count++];
- if(ch == '#') /* 空 */
- *T = NULL;
- else {
- *T = (BiTree)malloc(sizeof(BiTNode)); /* 生成根结点 */
- if(!*T)
- exit(OVERFLOW);
- (*T)->data = ch;
- CreateBiTree(&(*T)->lchild); /* 构造左子树 */
- CreateBiTree(&(*T)->rchild); /* 构造右子树 */
- }
- }
- void InitBiTree(BiTree *T)
- {
- /* 操作结果:构造空二叉树T */
- *T = NULL;
- }
- void DestroyBiTree(BiTree *T)
- {
- /* 初始条件:二叉树T存在。操作结果:销毁二叉树T */
- if(*T) { /* 非空树 */
- if((*T)->lchild) /* 有左孩子 */
- DestroyBiTree(&(*T)->lchild); /* 销毁左孩子子树 */
- if((*T)->rchild) /* 有右孩子 */
- DestroyBiTree(&(*T)->rchild); /* 销毁右孩子子树 */
- free(*T); /* 释放根结点 */
- *T = NULL; /* 空指针赋0 */
- }
- }
- /*广度优先遍历,层序*/
- void BFSTree(BiTree T)
- {
- LinkQueue Q;
- BiTNode e;
- InitQueue(&Q);
- EnQueue(&Q,*T);
- printf("BFSTree: ");
- while(!QueueEmpty( Q)){
- DeQueue(&Q, &e);
- printf("%c",e.data);
- if(T->lchild != NULL)
- {
- EnQueue(&Q, *(T->lchild));
- }
- if(T->rchild != NULL)
- {
- EnQueue(&Q, *(T->rchild));
- }
- GetHead_Q(Q, &e);
- T = &e;
- }
- printf("\n");
- DestroyQueue(&Q);
- }
- /*深度优先遍历,前序*/
- void DFSTree(BiTree T)
- {
- LinkStack S;
- BiTNode e;
- InitStack(&S);
- Push(&S, *T);
- printf("DFSTree: ");
- while(!StackEmpty(S)){
- Pop(&S, &e);
- printf("%c",e.data);
- if(T->rchild != NULL)
- {
- Push(&S, *(T->rchild));
- }
- if(T->lchild != NULL)
- {
- Push(&S, *(T->lchild));
- }
- GetTop(S, &e);
- T = &e;
- }
- printf("\n");
- ClearStack(&S);
- }
- int main(void)
- {
- BiTree t;
- InitBiTree(&t);
- StrAssign(str,"abd##e##cf##g##");
- CreateBiTree(&t);
- BFSTree(t);
- DFSTree(t);
- DestroyBiTree(&t);
- }
。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。
#include"iostream.h"
template <class T>
struct BiNode
{
T data;
BiNode<T>*lchild, * rchild;
};
template <class T>
class BiTree
{
private:
BiNode <T>*root;
void creat(BiNode<T>*&r);
void Release(BiNode<T>*r);
void Preorder(BiNode<T>*r);
void Inorder(BiNode<T>*r);
void Postorder(BiNode<T>*r);
void Levelorder(BiNode<T>*r);
public:
BiTree()
{
root=NULL;creat(root);
}
~BiTree()
{
Release(root);
}
void Pre()
{
Preorder(root);
}
void In()
{
Inorder(root);
}
void Post()
{
Postorder(root);
}
void Level()
{
Levelorder(root);
}
};
template<class T>
void BiTree<T>::Levelorder (BiNode<T>*r)//层序遍历
{
BiNode<T>*Q[100];
int front,rear;
BiNode<T>* q;
front=rear=0;
if(r==NULL)return;
Q[++rear]=r;
while(front!=rear)
{
q=Q[++front];
cout<<q->data;
if(q->lchild!=NULL)
Q[++rear]=q->lchild;
if(q->rchild!=NULL)
Q[++rear]=q->rchild;
}
}
template<class T>
void BiTree<T>::Preorder (BiNode<T>*r)//前序遍历
{
if(r==NULL) return;
else
{
cout<<r->data;
Preorder(r->lchild);
Preorder(r->rchild);
}
}
template<class T>
void BiTree<T>::Postorder (BiNode<T>*r)//后序遍历
{
if(r==NULL) return;
else
{
Postorder(r->lchild);
Postorder(r->rchild);
cout<<r->data;
}
}
template<class T>
void BiTree<T>::Inorder (BiNode<T>*r)//中序遍历
{
if(r==NULL) return;
else
{
Inorder(r->lchild);
cout<<r->data;
Inorder(r->rchild);
}
}
template<class T>
void BiTree<T>::creat (BiNode<T> *&r)
{
char ch;
cin>>ch;
if(ch=='#')r=NULL;//#表示空节点
else
{
r=new BiNode<T>;
r->data=ch;
creat(r->lchild);
creat(r->rchild);
}
}
template<class T>
void BiTree<T>::Release (BiNode<T>*r)
{
if(r!=NULL)
{
Release(r->lchild);
Release(r->rchild);
delete r;
}
}
void main()
{
BiTree<char> au;
cout<<"输出后序遍历:"<<endl;
au.Post ();
cout<<endl;
cout<<"输出中序遍历:"<<endl;
au.In ();
cout<<endl;
cout<<"输出层序遍历:"<<endl;
au.Level ();
cout<<endl;
cout<<"输出前序遍历:"<<endl;
au.Pre ();
cout<<endl;
}
。。。。。。。。。。。。。。。。。
#include <iostream>
using namespace std;
typedef struct node {
char data;
struct node *lchild;
struct node *rchild;
}BiNode,*BiTree;
typedef struct node1{
BiTree data[30]; //默认30个元素 ,这里需要一个辅助堆栈!!!
int top;
}Stack;
void createTree(BiTree &T) //先序递归创建树,这里注意参数的类型,T的类型是 "*&" ,如果是 "**" 代码稍加改动就OK...
{
char ch;
cin.get(ch).get(); //过滤输入流中每次回车产生的回车符
if (ch==' ') T=NULL; //这里首先判断是不是空格,如果是,则为该节点赋NULL
else{
T=(BiTree)malloc(sizeof(BiNode));
T->data=ch;
createTree(T->lchild);
createTree(T->rchild);
}
}
void initstack(Stack *&st)
{
st=(Stack *)malloc(sizeof(Stack));
st->top=-1;
}
bool isempty(Stack *st)
{
return st->top==-1;
}
bool isfull(Stack *st)
{
return st->top==19;
}
void push(Stack *st,BiTree T)
{
if (!isfull(st))
st->data[++st->top]=T; //栈顶指针始终指向堆栈最上面可用的一个元素,因此入栈时候,先要将指针加1,然后再执行入栈操作!
else cout<<"已满"<<endl;
}
BiTree pop(Stack *st)
{
if (!isempty(st)) return st->data[st->top--];
}
BiTree gettop(Stack *st)
{
if (!isempty(st)) return st->data[st->top]; //出栈时,先取出栈顶指针指向的元素,然后再将指针减1,使其指向栈中下一个可用元素!
}
void preOrderNoRe(BiTree T) // 前序遍历
{
Stack *st;
initstack(st);
BiTree p;
p=T;
while (p!=NULL||!isempty(st))
{
while (p!=NULL)
{
cout<<p->data<<" ";
push(st,p);
p=p->lchild;
}
if (!isempty(st))
{
p=pop(st);
p=p->rchild;
}
}
}
void inOrderNoRe(BiTree T) //中序遍历
{
Stack *st;
initstack(st);
BiTree p;
p=T;
while (p!=NULL||!isempty(st))
{
while (p!=NULL)
{
push(st,p);
p=p->lchild;
}
if (!isempty(st))
{
p=pop(st);
cout<<p->data<<" ";
p=p->rchild;
}
}
}
void postOrderNoRe(BiTree T) //后序遍历
{
BiTree p;
Stack *st;
initstack(st);
p=T;
int Tag[20]; //栈,用于标识从左(0)或右(1)返回
while (p!=NULL || !isempty(st))
{
while (p!=NULL)
{
push(st,p);
Tag[st->top]=0;
p=p->lchild;
}
while (!isempty(st)&&Tag[st->top]==1)
{
p=pop(st);
cout<<p->data<<" ";
}
if (!isempty(st))
{
Tag[st->top]=1; //设置标记右子树已经访问
p=gettop(st);
p=p->rchild;
}
else break;
}
}
int main()
{
cout<<"Enter char one by one hicjiajia"<<endl;
BiNode *T;
createTree(T);
cout<<endl;
cout<<"preOrderNoRe: ";preOrderNoRe(T);cout<<endl;
cout<<"inOrderNoRe: ";inOrderNoRe(T);cout<<endl;
cout<<"postOrderNoRe: ";postOrderNoRe(T);cout<<endl;
system("pause");
return 0;
}
using namespace std;
typedef struct node {
char data;
struct node *lchild;
struct node *rchild;
}BiNode,*BiTree;
typedef struct node1{
BiTree data[30]; //默认30个元素 ,这里需要一个辅助堆栈!!!
int top;
}Stack;
void createTree(BiTree &T) //先序递归创建树,这里注意参数的类型,T的类型是 "*&" ,如果是 "**" 代码稍加改动就OK...
{
char ch;
cin.get(ch).get(); //过滤输入流中每次回车产生的回车符
if (ch==' ') T=NULL; //这里首先判断是不是空格,如果是,则为该节点赋NULL
else{
T=(BiTree)malloc(sizeof(BiNode));
T->data=ch;
createTree(T->lchild);
createTree(T->rchild);
}
}
void initstack(Stack *&st)
{
st=(Stack *)malloc(sizeof(Stack));
st->top=-1;
}
bool isempty(Stack *st)
{
return st->top==-1;
}
bool isfull(Stack *st)
{
return st->top==19;
}
void push(Stack *st,BiTree T)
{
if (!isfull(st))
st->data[++st->top]=T; //栈顶指针始终指向堆栈最上面可用的一个元素,因此入栈时候,先要将指针加1,然后再执行入栈操作!
else cout<<"已满"<<endl;
}
BiTree pop(Stack *st)
{
if (!isempty(st)) return st->data[st->top--];
}
BiTree gettop(Stack *st)
{
if (!isempty(st)) return st->data[st->top]; //出栈时,先取出栈顶指针指向的元素,然后再将指针减1,使其指向栈中下一个可用元素!
}
void preOrderNoRe(BiTree T) // 前序遍历
{
Stack *st;
initstack(st);
BiTree p;
p=T;
while (p!=NULL||!isempty(st))
{
while (p!=NULL)
{
cout<<p->data<<" ";
push(st,p);
p=p->lchild;
}
if (!isempty(st))
{
p=pop(st);
p=p->rchild;
}
}
}
void inOrderNoRe(BiTree T) //中序遍历
{
Stack *st;
initstack(st);
BiTree p;
p=T;
while (p!=NULL||!isempty(st))
{
while (p!=NULL)
{
push(st,p);
p=p->lchild;
}
if (!isempty(st))
{
p=pop(st);
cout<<p->data<<" ";
p=p->rchild;
}
}
}
void postOrderNoRe(BiTree T) //后序遍历
{
BiTree p;
Stack *st;
initstack(st);
p=T;
int Tag[20]; //栈,用于标识从左(0)或右(1)返回
while (p!=NULL || !isempty(st))
{
while (p!=NULL)
{
push(st,p);
Tag[st->top]=0;
p=p->lchild;
}
while (!isempty(st)&&Tag[st->top]==1)
{
p=pop(st);
cout<<p->data<<" ";
}
if (!isempty(st))
{
Tag[st->top]=1; //设置标记右子树已经访问
p=gettop(st);
p=p->rchild;
}
else break;
}
}
int main()
{
cout<<"Enter char one by one hicjiajia"<<endl;
BiNode *T;
createTree(T);
cout<<endl;
cout<<"preOrderNoRe: ";preOrderNoRe(T);cout<<endl;
cout<<"inOrderNoRe: ";inOrderNoRe(T);cout<<endl;
cout<<"postOrderNoRe: ";postOrderNoRe(T);cout<<endl;
system("pause");
return 0;
}