資料結構——二叉樹的建立、遍歷、求度數、深度
阿新 • • 發佈:2018-12-26
二叉樹的建立直接用遞迴操作即可
二叉樹的遍歷有三種
- 先序遍歷DLR:根節點->左子樹->右子樹
- 中序遍歷LDR:左子樹->根節點->右子樹。必須要有中序遍歷才能得到一棵二叉樹的正確順序
- 後續遍歷LRD:左子樹->右子樹->根節點。需要棧的支援。
- 特殊的遍歷方法就是層次遍歷,即按照二叉樹每一層列印
獲取葉子數目
直接判斷每個節點的下一結點是否為空即可
求二叉樹的深度
用遞迴演算法分別求二叉樹的左右子樹的深度,取最大值
求二叉樹的度數
設定num為全域性變數,即每次遍歷一個結點,num加1
#include <stdio.h> #include <stdlib.h> #define MAXSIZE 100 //二叉樹 typedef struct node{ char data;//資料域 struct node *lchild,*rchild;//指標域 }BinTree; //線索二叉樹 typedef struct ThreadTNode{ int lTag,rTag;//左右標誌域 char data;//資料域 struct ThreadTNode *lchild,*rchild;//左右孩子指標域 }ThreadTNode,*ThreadTree; //建立普通二叉樹 BinTree *creatTree() { BinTree *Tree = NULL; char ch; ch = getchar();//輸入一個字元 if(ch != '#') { Tree = (BinTree*)malloc(sizeof(BinTree));//分配空間 Tree->data = ch; Tree->lchild = creatTree();//建立左子樹 Tree->rchild = creatTree();//建立右子樹 } return Tree; } /*先序遍歷二叉樹*/ void preorder(BinTree *Tree) { if(Tree)//二叉樹不為空 { printf("%c",Tree->data);//輸出節點的值 preorder(Tree->lchild);//遍歷左子樹 preorder(Tree->rchild);//遍歷右子樹 } } /*中序遍歷二叉樹*/ void inorder(BinTree *Tree) { if(Tree)//二叉樹不為空 { inorder(Tree->lchild);//遍歷左子樹 printf("%c",Tree->data);//輸出節點的值 inorder(Tree->rchild);//遍歷右子樹 } } /*後序遍歷二叉樹*/ void postorder(BinTree *Tree) { if(Tree)//二叉樹不為空 { postorder(Tree->lchild);//遍歷左子樹 postorder(Tree->rchild);//遍歷右子樹 printf("%c",Tree->data);//輸出節點的值 } } /*中序輸出二叉樹非遞迴演算法*/ void inorderTraverse(BinTree *bt) { BinTree *stack[MAXSIZE],*p;//定義順序棧stack,最大值為100 int top = 0;//定義棧頂指標 p = bt; do { while(p != NULL)//順著左鏈搜尋到盡頭 { stack[top++] = p;//當二叉樹不為空時根指標入棧 p = p->lchild;//順著左鏈搜尋 } if(top > 0) { p = stack[top-1];//棧不為空時取出棧頂元素 printf("%c",stack[top-1]->data);//輸出當前訪問的根節點 top--; p = p->rchild;//順著右鏈搜尋 } } while(top != 0||p != NULL);//當遍歷沒有結束時繼續訪問 } /*獲取葉子數目*/ void getLeafNumber(BinTree *T,int *count) { if(T) { if((!T->lchild)&&(!T->rchild))//左右孩子都為空 { (*count)++;//對葉子數目計數 } getLeafNumber(T->lchild,count); getLeafNumber(T->rchild,count); } } /*獲取二叉樹的深度*/ int getDepth(BinTree *T) { int higthLeft,highRight; if(!T) return 0; else { higthLeft = getDepth(T->lchild); highRight = getDepth(T->rchild); if(higthLeft >= highRight) return higthLeft+1 ; else return highRight+1 ; } } /*建立線索二叉樹的中序線索連結串列*/ ThreadTree pre;//pre定義全域性變數,始終指向當前節點的前驅 ThreadTree inorderThread(ThreadTree bt) { ThreadTree head;//建立二叉樹bt的中序線索連結串列 head = (ThreadTree)malloc(sizeof(ThreadTNode)); if(head) { printf("分配記憶體錯誤\n"); return NULL; } head->lTag = 0; head->rTag = 1;//設定頭結點的線索標誌域 head->rchild = head;//頭結點右指標指向自身 if(bt == NULL) head->lchild = head;//若二叉樹bt為空,左線索指向自身 else { head->lchild = head;//若二叉樹非空則左線索指向二叉樹根節點bt處 pre = head;//pre指向當前節點的前驅 inorderThread(bt);//中序遍歷進行中序線索化 pre->rchild = head;//最後一個節點右線索化 pre->rTag = 1;//最後一個節點標誌域置為線索 pre->rchild = pre;//頭結點的右指標指向最後一個節點 } return head; } int main() { int number = 0; BinTree *T = creatTree(); printf("先序遍歷二叉樹結果\n"); preorder(T); printf("\n"); printf("中序遍歷二叉樹結果\n"); inorder(T); printf("\n"); printf("後序遍歷二叉樹結果\n"); postorder(T); printf("\n"); printf("中序輸出二叉樹非遞迴演算法\n"); inorderTraverse(T); printf("\n"); printf("獲取葉子數目\n"); getLeafNumber(T,&number); printf("%d",number); printf("\n"); printf("獲取二叉樹的深度\n"); printf("%d",getDepth(T)); printf("\n"); //ThreadTNode *T; return 0; }