二叉樹的廣度遍歷和深度遍歷()
圖的深度優先搜尋法是樹的先根遍歷的推廣,它的基本思想是:從圖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;
}
相關文章
- Javascript樹(一):廣度遍歷和深度遍歷JavaScript
- 二叉樹的深度優先遍歷和廣度優先遍歷二叉樹
- js實現深度優先遍歷和廣度優先遍歷JS
- 二叉樹的深度、寬度遍歷及平衡樹二叉樹
- python 實現二叉樹的深度&&廣度優先遍歷Python二叉樹
- 二叉樹的建立、前序遍歷、中序遍歷、後序遍歷二叉樹
- 二叉樹建立,前序遍歷,中序遍歷,後序遍歷 思路二叉樹
- 二叉樹---遍歷二叉樹
- 二叉樹遍歷二叉樹
- 二叉樹的遍歷二叉樹
- 根據二叉樹的前序遍歷和中序遍歷輸出二叉樹;二叉樹
- 深度優先遍歷,廣度優先遍歷實現物件的深拷貝物件
- 建立二叉樹:層次遍歷--樹的寬度高度,後序遍歷--祖先節點二叉樹
- LintCode 前序遍歷和中序遍歷樹構造二叉樹二叉樹
- 二叉樹遍歷方法二叉樹
- 二叉樹遍歷 -- JAVA二叉樹Java
- JAVA遍歷二叉樹Java二叉樹
- 二叉樹的遍歷 → 不用遞迴,還能遍歷嗎二叉樹遞迴
- 完全二叉樹的遍歷二叉樹
- 二叉樹的建立、遍歷、廣義錶轉換二叉樹
- 144.二叉樹的前序遍歷145.二叉樹的後序遍歷 94.二叉樹的中序遍歷二叉樹
- 面試中很值得聊的二叉樹遍歷方法——Morris遍歷面試二叉樹
- C++樹——遍歷二叉樹C++二叉樹
- 玩轉二叉樹(樹的遍歷)二叉樹
- 迴圈遍歷二叉樹二叉樹
- 二叉樹四種遍歷二叉樹
- 二叉樹--後序遍歷二叉樹
- 層序遍歷二叉樹二叉樹
- 二叉樹的遍歷實現二叉樹
- 二叉樹的遍歷筆記二叉樹筆記
- 二叉樹的層序遍歷二叉樹
- 二叉樹的按層遍歷二叉樹
- 【練習】二叉樹的遍歷二叉樹
- 二叉樹的建立與遍歷二叉樹
- UVA 536 二叉樹的遍歷二叉樹
- 二叉樹的遍歷演算法【和森林的遍歷】【PHP 原始碼測試】二叉樹演算法PHP原始碼
- 二叉樹排序樹的建立,遍歷和刪除二叉樹排序
- 根據前序遍歷序列、中序遍歷序列,重建二叉樹二叉樹