當(dāng)前位置:
首頁 >
二叉树 —— 创建二叉树 先序遍历 、中序遍历、后序遍历(递归方式、非递归方式)
發(fā)布時(shí)間:2025/10/17
32
豆豆
生活随笔
收集整理的這篇文章主要介紹了
二叉树 —— 创建二叉树 先序遍历 、中序遍历、后序遍历(递归方式、非递归方式)
小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.
#include<stdio.h>
#include<malloc.h>
#include<stdlib.h>
typedef char DataType;
#define MaxSize 100
typedef struct Node
{DataType data;struct Node *lchild;struct Node *rchild;
}*BiTree,BitNode;
void InitBitTree(BiTree *T);/*樹的初始化*/
void CreaBitTree(BiTree *T);/*按照先序輸入字符序列遞歸創(chuàng)建二叉樹*/
void PreOrderTraverse(BiTree T);/*二叉樹的先序遍歷的遞歸函數(shù)聲明*/
void InOrderTraverse(BiTree T);/*二叉樹的中序遍歷的遞歸函數(shù)聲明*/
void PostOrderTraverse(BiTree T);/*二叉樹的后序遍歷的遞歸函數(shù)聲明*/
void PreOrderTraverse2(BiTree T);/*二叉樹的先序遍歷的非遞歸函數(shù)聲明*/
void InOrderTraverse2(BiTree T);/*二叉樹的中序遍歷的非遞歸函數(shù)聲明*/
void PostOrderTraverse2(BiTree T);/*二叉樹的后序遍歷的非遞歸函數(shù)聲明*/
void main()
{BiTree T,root;InitBitTree(&T);printf("根據(jù)輸入二叉樹的先序序列創(chuàng)建二叉樹('#'表示結(jié)束):\n");CreaBitTree(&T);printf("二叉樹的先序遍歷:\n");printf("遞歸方式:\t");PreOrderTraverse(T);printf("\n");printf("非遞歸方式:\t");PreOrderTraverse2(T);printf("\n");printf("二叉樹的中序遍歷:\n");printf("遞歸方式:\t");InOrderTraverse(T);printf("\n");printf("非遞歸方式:\t");InOrderTraverse2(T);printf("\n");printf("二叉樹的后序遍歷:\n");printf("遞歸方式:\t");PostOrderTraverse(T);printf("\n");printf("非遞歸方式:\t");PostOrderTraverse2(T);printf("\n");}
void InitBitTree(BiTree *T)
{*T = NULL;
}
void CreaBitTree(BiTree *T)
{DataType ch;scanf(" %c",&ch);if(ch == '#')*T = NULL;else{*T = (BiTree)malloc(sizeof(BitNode));//生成根節(jié)點(diǎn)if(!(*T))exit(-1);(*T)->data = ch;CreaBitTree(&((*T)->lchild));//構(gòu)造左子樹CreaBitTree(&((*T)->rchild));//構(gòu)造右子樹}
}
void PreOrderTraverse(BiTree T)
{if(T)//如果二叉樹不為空{(diào)printf("%2c",T->data);//訪問根節(jié)點(diǎn)PreOrderTraverse(T->lchild);//先序遍歷左子樹PreOrderTraverse(T->rchild);//先序遍歷右子樹}
}
void InOrderTraverse(BiTree T)
{if(T)//如果二叉樹不為空{(diào)InOrderTraverse(T->lchild);//中序遍歷左子樹printf("%2c",T->data);//訪問根節(jié)點(diǎn)InOrderTraverse(T->rchild);//中序遍歷右子樹}
}
void PostOrderTraverse(BiTree T)
{if(T){PostOrderTraverse(T->lchild);//后序遍歷左子樹PostOrderTraverse(T->rchild);//后序遍歷右子樹printf("%2c",T->data);//訪問根節(jié)點(diǎn)}
}
void PreOrderTraverse2(BiTree T)
{BiTree stack[MaxSize]; //定義一個(gè)棧 用于存放結(jié)點(diǎn)的指針int top;//定義棧頂指針BitNode *p; //定義一個(gè)節(jié)點(diǎn)的指針top = 0; //初始化棧p = T;while(p != NULL || top>0){while(p != NULL) //如果p不是空,訪問根節(jié)點(diǎn),遍歷左子樹{printf("%2c",p->data); //訪問根節(jié)點(diǎn)stack[top++] = p; //將p入棧p = p->lchild; //遍歷左子樹}if(top > 0) //如果棧不為空{(diào)p = stack[--top]; //棧頂元素出棧p = p->rchild; //遍歷右子樹}}}
void InOrderTraverse2(BiTree T)
{BiTree stack[MaxSize];int top;BitNode *p;top = 0;p = T;while(p != NULL || top > 0){while(p != NULL){stack[top++] = p;p = p->lchild;}if(top > 0){p = stack[--top];printf("%2c",p->data);p = p->rchild;}}
}
void PostOrderTraverse2(BiTree T)
{BiTree stack[MaxSize];int top;BitNode *p,*q;top = 0;p = T,q = NULL;while(p != NULL || top > 0){while(p != NULL){stack[top++] = p;p = p->lchild;}if(top > 0){p = stack[top-1];//取棧頂元素if(p->rchild == NULL || p->rchild ==q) //如果p沒有右孩子結(jié)點(diǎn),或者右孩子結(jié)點(diǎn)已經(jīng)訪問過{printf("%2c",p->data); //訪問根節(jié)點(diǎn)q = p;p = NULL;top--;}elsep = p->rchild;}}}
~
~
//創(chuàng)建一個(gè)存儲(chǔ)整數(shù)的二叉樹 //首先 創(chuàng)建一個(gè)跟節(jié)點(diǎn) 所有節(jié)點(diǎn)的創(chuàng)建方式都相同 //這個(gè)函數(shù)返回指向新建Node對(duì)象的指針,要為新的二叉樹創(chuàng)建根節(jié)點(diǎn),可以使用這個(gè)函數(shù) struct Node *createnode(long value) {struct Node *pNode = (struct Node *)malloc(sizeof(struct Node));pNode->item = value; //set the valuepNode->count = 1;pNode->pLeft = pNode->pRight = NULL;return pNode; } long newvalue; printf("Enter the node value:"); //從鍵盤上讀取存儲(chǔ)值后 scanf("%ld",newvalue); //調(diào)用函數(shù) 在堆上創(chuàng)建一個(gè)新的節(jié)點(diǎn) 不要忘記使用完畢以后釋放節(jié)點(diǎn)內(nèi)存 struct Node *pRoot = createnode(newvalue); //二叉樹是應(yīng)用遞歸的一個(gè)領(lǐng)域,插入節(jié)點(diǎn)的過程涉及到以相同的方式查看一系列節(jié)點(diǎn),這里使用遞歸的一個(gè)強(qiáng)烈的暗示。 //用下面的函數(shù)在樹中添加一個(gè)已有的節(jié)點(diǎn) add a new node to a tree struct Node *addnod(long value,struct Node* pNode) {if(pNode == NULL)return createnode(value);//把根節(jié)點(diǎn)作為第二個(gè)變?cè)獋魉蜁r(shí)//如果value等于當(dāng)前節(jié)點(diǎn)的值,就不需要?jiǎng)?chuàng)建新節(jié)點(diǎn),只遞增當(dāng)前節(jié)點(diǎn)中的計(jì)數(shù)器,并返回該節(jié)點(diǎn)if(value == pNode->item){++pNode -> count;return pNode;}//如果value小于當(dāng)前節(jié)點(diǎn)的值,就需要查看左子節(jié)點(diǎn),如果左節(jié)點(diǎn)的指針是NULL,就創(chuàng)建一個(gè)包含value的新節(jié)點(diǎn),使之成為左子節(jié)點(diǎn)。如果左節(jié)點(diǎn)存在,就遞歸調(diào)用addnod()函數(shù),把指向左子節(jié)點(diǎn)的指針作為第二個(gè)變?cè)?。if(value < pNode->item){if(pNode->left == NULL){pNode->pLeft = createnode(value);return pNode->pLeft;}else{return addnode(value,pNode->pLeft);}}else{if(pNode->pRight == NULL){pNode->pRight = createnode(value);return pNode->pRight}else{return addnode(value,pNode->pRight);}} }//無論調(diào)用遞歸函數(shù)時(shí)執(zhí)行了什么,該函數(shù)都返回一個(gè)插入值的節(jié)點(diǎn)的指針,這可能時(shí)一個(gè)新節(jié)點(diǎn),也可以是一個(gè)其值已經(jīng)存在于樹中的節(jié)點(diǎn) do {printf("Enter the node value:");scanf(" %ld",&newvalue);if(pRoot == NULL)pRoot = createnode(newvalue);elseaddnode(newvalue,pRoot);printf("\nDo you want to enter another(y or n)");scanf(" %c",&answer); }while(totlwer(answer) == 'y');
?
[root@J01051386 Test_20180418]# ./a.out
根據(jù)輸入二叉樹的先序序列創(chuàng)建二叉樹('#'表示結(jié)束):
e#
r#
G#
#
二叉樹的先序遍歷:
遞歸方式:?? ? e r G
非遞歸方式:?? ? e r G
二叉樹的中序遍歷:
遞歸方式:?? ? e r G
非遞歸方式:?? ? e r G
二叉樹的后序遍歷:
遞歸方式:?? ? G r e
非遞歸方式:?? ? G r e
//創(chuàng)建一個(gè)存儲(chǔ)整數(shù)的二叉樹 //首先 創(chuàng)建一個(gè)跟節(jié)點(diǎn) 所有節(jié)點(diǎn)的創(chuàng)建方式都相同 //這個(gè)函數(shù)返回指向新建Node對(duì)象的指針,要為新的二叉樹創(chuàng)建根節(jié)點(diǎn),可以使用這個(gè)函數(shù) struct Node *createnode(long value) {struct Node *pNode = (struct Node *)malloc(sizeof(struct Node));pNode->item = value; //set the valuepNode->count = 1;pNode->pLeft = pNode->pRight = NULL;return pNode; } long newvalue; printf("Enter the node value:"); //從鍵盤上讀取存儲(chǔ)值后 scanf("%ld",newvalue); //調(diào)用函數(shù) 在堆上創(chuàng)建一個(gè)新的節(jié)點(diǎn) 不要忘記使用完畢以后釋放節(jié)點(diǎn)內(nèi)存 struct Node *pRoot = createnode(newvalue); //二叉樹是應(yīng)用遞歸的一個(gè)領(lǐng)域,插入節(jié)點(diǎn)的過程涉及到以相同的方式查看一系列節(jié)點(diǎn),這里使用遞歸的一個(gè)強(qiáng)烈的暗示。 //用下面的函數(shù)在樹中添加一個(gè)已有的節(jié)點(diǎn) add a new node to a tree struct Node *addnod(long value,struct Node* pNode) {if(pNode == NULL)return createnode(value);//把根節(jié)點(diǎn)作為第二個(gè)變?cè)獋魉蜁r(shí)//如果value等于當(dāng)前節(jié)點(diǎn)的值,就不需要?jiǎng)?chuàng)建新節(jié)點(diǎn),只遞增當(dāng)前節(jié)點(diǎn)中的計(jì)數(shù)器,并返回該節(jié)點(diǎn)if(value == pNode->item){++pNode -> count;return pNode;}//如果value小于當(dāng)前節(jié)點(diǎn)的值,就需要查看左子節(jié)點(diǎn),如果左節(jié)點(diǎn)的指針是NULL,就創(chuàng)建一個(gè)包含value的新節(jié)點(diǎn),使之成為左子節(jié)點(diǎn)。如果左節(jié)點(diǎn)存在,就遞歸調(diào)用addnod()函數(shù),把指向左子節(jié)點(diǎn)的指針作為第二個(gè)變?cè)?。if(value < pNode->item){if(pNode->left == NULL){pNode->pLeft = createnode(value);return pNode->pLeft;}else{return addnode(value,pNode->pLeft);}}else{if(pNode->pRight == NULL){pNode->pRight = createnode(value);return pNode->pRight}else{return addnode(value,pNode->pRight);}} }//無論調(diào)用遞歸函數(shù)時(shí)執(zhí)行了什么,該函數(shù)都返回一個(gè)插入值的節(jié)點(diǎn)的指針,這可能時(shí)一個(gè)新節(jié)點(diǎn),也可以是一個(gè)其值已經(jīng)存在于樹中的節(jié)點(diǎn) do {printf("Enter the node value:");scanf(" %ld",&newvalue);if(pRoot == NULL)pRoot = createnode(newvalue);elseaddnode(newvalue,pRoot);printf("\nDo you want to enter another(y or n)");scanf(" %c",&answer); }while(totlwer(answer) == 'y');
總結(jié)
以上是生活随笔為你收集整理的二叉树 —— 创建二叉树 先序遍历 、中序遍历、后序遍历(递归方式、非递归方式)的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 结构体的嵌套 自身嵌套 相互嵌套
- 下一篇: 函数 —— fgets()