二叉樹-連結串列儲存結構及其簡單演算法
阿新 • • 發佈:2018-12-19
適用於層次結構的資料(大部分演算法用遞迴思想)
#include <stdio.h> #define Max 100 結構體 typedef struct TNode{ int data; struct Node * lchild;//左孩子結點 struct Node * rchild;//右孩子節點 }TNode; //先序遍歷(/根結點->左孩子->右孩子) void preTrave(TNode* node){ if(node!=NULL){ printf("%d",node->data); preTrave(node->lchild); preTrave(node->rchild); } } //中序遍歷(左孩子->根結點->右孩子) void midTrave(TNode* node){ if(node!=NULL){ midTrave(node->lchild); printf("%d",node->data); midTrave(node->rchild); } } //後序遍歷(左孩子->右孩子->根結點) void lateTrave(TNode * node){ if(node!=NULL){ lateTrave(node->lchild); lateTrave(node->rchild); printf("%d",node->data;) } } //層序遍歷(利用順序(迴圈)佇列的特性) void cTrave(TNode *node){ TNode * que[Max];//存放樹結點 int front,rear; front = rear = 0;//佇列初始化 TNode * s; if(node!=NULL){ rear = (rear + 1)%Max; que[rear] = node;//根結點入隊 while(rear != front){//如果隊不空 front = (front+1) %Max; s = que[front];//根結點出隊 print("%d",s->data); if(s->lchild!=NULL){//如果左孩子不為空 rear = (rear + 1)%Max; que[rear] = s->lchild;//左孩子結點入隊 } if(s->rchild!=NULL){//如果右孩子不為空 rear = (rear +1)%Max; que[rear] = s->rchild;//右孩子入隊 } } } } //求寬度(利用順序非迴圈的佇列,增加一個結構體來儲存結點指標以及結點所在的層次號) typedef struct T{ TNode * node;//結點指標 int no;//結點所在層次號 } int getWidth(TNode * node){ T que[Max]; int front,rear;//定義一個順序非迴圈佇列 front = rear = 0; int i,j,n,max,Lno; TNode s; if(node!=NULL){ ++rear; que[rear].node = node;//根結點入隊 que[rear].no = 1;//根結點所在層次為1 while(front!=rear){//如果隊不空 ++front; s = que[front].node;//結點出隊 Lno = que[front].no;//關鍵一步:儲存當前結點的層次號 if(s->lchild!=NULL){//左孩子不空則將左孩子入隊 ++rear; que[rear].node = s->lchild; que[rear].no = Lno+!;//關鍵一步:根據當前結點層次號計算其孩子結點層次號 } if(s->rchild!=NULL){//如果右孩子不為空則將右孩子入隊 ++rear; que[rear].node = s->rchild; que[rear].no = Lno+!;//關鍵一步:根據當前結點層次號計算其孩子結點層次號 } }//迴圈結束,Lno中儲存了這棵二叉樹中最大的層數 //以下程式碼找出含有結點最多的層中的結點數 max = 0; for(i=0;i<=Lno;i++){ n = 0; for(j=1;j<=rear;j++){ if(que[j].no==i){ ++n; } } if(max<n){ max = n; } } return max; }else{ return 0;//空樹直接返回0 } } //求二叉樹深度(遞迴) int getDepth(TNode * node){ int ld;rd;//用於接收左右深度 if(node!=NULL){ ld = getDepth(node->lchild); rd = getDepth(node->rchild); return (ld>rd?ld:rd)+1' }else{ return 0; } } //求值為key的結點在二叉樹中的位置 void getNo(TNode * root,int key,TNode ** node){ if(root!=NULL){ if(root->data == key){ (*node) = root; }else{ getNo(root->lchild,key,node); if(node!=NULL){ getNO(root->rchild,key,node); } } } } //二叉樹的創立(遞迴) TNode * init(){ int data; scanf("%d",&data); TNode * node = NULL; if(data!=-1){ node = (TNode*)malloc(sizeof(TNode)); node->data = data;//給樹節點賦值 root->lchild = init();//建立左孩子 root->rchild = init();//建立右孩子 } return node; } //二叉樹的銷燬(後序遍歷思想) void destory(TNode * node){ if(node!=NULL){ destory(node->lchild); destory(node->rchild); free(node);//釋放結點 } } //二叉排序樹的插入(左孩子小右孩子大) void insertNode(TNode ** node,int key){ if(node!=NULL){//結點是否為空;不為空的比較大小插入 if(key<(*node)->data){//比根結點小則在左邊 insertNode((*root)->lchild,key); }else{//比根結點大或者相等則在右邊 insetNode((*node)->rchild,key); } }else{//為空則新建結點 (*root) = (TNode*)malloc(sizeof(TNode)); (*root)->data =key; } } //在二叉排序樹中查詢某個結點 TNode * findNode(TNode * node,int key){ if(node!=NULL){ if(key==node->data){ return node; }else if(key<node->data){ findNode(node->lchild,key); }else{ findNode(node->rchild,key); } }else{ return NULL; } } //表示式(a-(b+c))*(d/e),編寫程式求出該表示式的值(使用後序遍歷)