二叉链表表示的二叉树以及操作若干

  1 #include<stdio.h>
  2 #include<stdlib.h>
  3 
  4 #define OK 1
  5 #define ERROR 0
  6 #define YES 1
  7 #define NO 0
  8 
  9 typedef int Status;
 10 typedef char ElemType;
 11 
 12 typedef struct BiTreeNode{
 13     ElemType data;
 14     struct BiTreeNode *lchild, *rchild; 
 15 }BiTreeNode, *BiTree;
 16 
 17 typedef struct QueueNode{
 18     BiTreeNode* binary_tree_node;        //存放的"数据"是二叉树的节点的指针
 19     struct QueueNode* next;
 20 }QueueNode, *QueueNodePtr;
 21 typedef struct LinkQueue{
 22     QueueNodePtr front;
 23     QueueNodePtr rear;
 24 }LinkQueue, *Queue; 
 25 
 26 
 27 //创建头结点,初始化
 28 Status InitQueue(Queue q){    //注意这里的参数不是Queue *q,因为不是要为q分配空间
 29                 //而是为了q中的front和rear
 30     q->front = (QueueNode*)malloc(sizeof(struct QueueNode));
 31     if( !q->front )
 32         return ERROR;
 33     q->rear = q->front;
 34     q->front->next = NULL;
 35     return OK;
 36 }
 37 //入队
 38 Status EnterQueue(Queue q, BiTreeNode* binaryTreeNode){
 39     QueueNode* new = (QueueNode*)malloc(sizeof(struct QueueNode));
 40     if( !new )
 41         return ERROR;
 42     new->binary_tree_node = binaryTreeNode;
 43     new->next = q->rear->next;
 44     q->rear->next = new;
 45     q->rear = new;
 46     return OK;
 47 }
 48 //出队
 49 Status DeleteQueue(Queue q, BiTreeNode** binaryTreeNode){
 50     if( q->front == q->rear ){
 51         printf("Queue Empty!\n");
 52         return ERROR;
 53     }
 54     QueueNodePtr t;
 55     t = q->front->next;
 56     *binaryTreeNode = t->binary_tree_node;
 57     q->front->next = t->next;
 58     free(t);
 59     if( t == q->rear )
 60         q->rear = q->front;
 61     return OK;
 62 }
 63 Status IsQueueEmpty(Queue q){
 64     return q->front == q->rear ? OK : ERROR;
 65 }
 66 
 67 //test Queue
 68 //int main(){
 69 /*                    测试  1
 70  * 如何为指针分配空间,都是4?
 71  * 下面的测试中出现了结构对齐的问题。
 72     printf("%d\n",sizeof(ElemType));
 73     printf("%d\n",sizeof(struct QueueNode*));
 74     printf("%d\n",sizeof(QueueNode));
 75     printf("%d\n",sizeof(QueueNodePtr));
 76 
 77     printf("%d\n",sizeof(LinkQueue));
 78     printf("%d\n",sizeof(Queue));
 79 
 80     int *p;
 81     printf("%d\n",sizeof(p));
 82 */
 83 
 84 /*                             测试   2 √
 85  * 原来没有写下面这个函数,导致出错:
 86             使用指针之前请保证它有合法值。
 87             main里的三个指针都没有合法值。(from CSDN)
 88     
 89         ————————————————————————————————————————————————————————————
 90         Status InitBinaryTreeNode(BiTree *T){
 91             *T = (BiTreeNode*)malloc(sizeof(struct BiTreeNode));
 92             if( !*T )
 93                 return ERROR;
 94             return OK;
 95         }
 96         ————————————————————————————————————————————————————————————
 97     LinkQueue* q;
 98     InitQueue(q);
 99     BiTree p;
100     InitBinaryTreeNode(&p);
101     p->data = 'a';
102     printf("%c ",p->data);
103     BiTree t;
104     InitBinaryTreeNode(&t);
105     t->data = 'c';
106     printf("%c ",t->data);
107 */                
108 /*                    测试  3
109     LinkQueue* q;
110     InitQueue(q);
111     BiTreeNode *p,*r;
112     InitBinaryTreeNode(&p);
113     InitBinaryTreeNode(&r);
114     p->data = 'a';
115     printf("%c \n",p->data);
116     EnterQueue(q,p);
117     DeleteQueue(q,&r);
118     printf("%c  \n",r->data);
119 
120 //    return OK;
121 }
122 //test Queue end
123 */
124 
125 
126 //初始化二叉树,在要创建二叉树之前调用
127 Status InitBiTree(BiTree *T){
128     *T = NULL;
129     return OK;
130 }
131 //初始化二叉树节点。单个节点使用的时候调用此函数,不然指针会成为野指针
132 Status InitBinaryTreeNode(BiTree *T){
133     *T = (BiTreeNode*)malloc(sizeof(struct BiTreeNode));
134     if( !*T )
135         return ERROR;
136     return OK;
137 }
138 //使用前序遍历的结构进行二叉树的创建
139 Status CreateBiTree_PreOrder(BiTree* T){
140     ElemType c;
141     scanf("%c", &c);
142     if( ' ' == c ){
143         *T = NULL;
144     }
145     else{
146         *T = (BiTree)malloc(sizeof(struct BiTreeNode));
147         if( !*T )
148             return ERROR;
149         (*T)->data = c;
150         CreateBiTree_PreOrder(&(*T)->lchild);
151         CreateBiTree_PreOrder(&(*T)->rchild);
152     }
153     return OK;
154 }
155 void visit(ElemType c,int level){
156     printf("  %c  level is:%d\n", c, level);
157 }
158 void visit_2(ElemType c){
159     printf("%c  ", c);
160 }
161         //递归的前序遍历二叉树
162 Status PreOrderTraverse(BiTree T,int level){
163     if( T ){
164         visit(T->data,level);
165         PreOrderTraverse(T->lchild,level + 1);
166         PreOrderTraverse(T->rchild,level + 1);
167     }
168     return OK;
169 }
170         //递归的中序遍历二叉树
171 Status InOrderTraverse(BiTree T,int level){
172     if( T ){
173         InOrderTraverse(T->lchild,level + 1);
174         visit(T->data,level);
175         InOrderTraverse(T->rchild,level + 1);
176     }
177     return OK;
178 }
179         //递归的后序遍历二叉树
180 Status PostOrderTraverse(BiTree T,int level){
181     if( T ){
182         PostOrderTraverse(T->lchild,level + 1);
183         PostOrderTraverse(T->rchild,level + 1);
184         visit(T->data,level);
185     }
186     return OK;
187 }
188         //层序遍历二叉树<<非递归>>
189 //要进行层序遍历需要借助于队列的辅助:先将二叉树的根入队列,然后将其
190 //出队列,visit。如果该根有左孩子,则入队;如果该根有右孩子,则入队。
191 //然后出队,对该出队的节点进行以上的相同的访问。直到对空
192 Status LevelOrderTraverse(BiTree T){
193     LinkQueue *q = (LinkQueue*)malloc(sizeof(LinkQueue));    /*有几次代码出错都是
194                                    因为这个,指针q没有
195                                    指向。
196                                   */
197     InitQueue(q);
198     BiTreeNode* nodePtr;
199     InitBinaryTreeNode(&nodePtr);
200     EnterQueue(q,T);
201     while( !IsQueueEmpty(q) ){
202         DeleteQueue(q, &nodePtr);
203         visit_2(nodePtr->data);
204         if( nodePtr->lchild != NULL ){
205             EnterQueue(q,nodePtr->lchild);
206         }
207         if( nodePtr->rchild != NULL ){
208             EnterQueue(q,nodePtr->rchild);
209         }
210     }
211     return OK;
212 }
213 //判断二叉树是否为空
214 Status IsTreeEmpty(BiTree T){
215     return T == NULL ? OK : ERROR;
216 }
217 //计算二叉树的深度
218 int BiTreeDepth(BiTree T){
219     int i = 0,j = 0;
220     if( !T )
221         return 0;
222     if( T->lchild )
223         i = BiTreeDepth(T->lchild);
224     else
225         i = 0;
226     if( T->rchild )
227         j = BiTreeDepth(T->rchild);
228     else
229         j = 0;
230     return i>j ? i+1 : j+1;
231 }
232 /*             判断一棵二叉树是否是完全二叉树:
233  * 思路: 借助于队列,先将root入队,当队列不为空的时候,出队一个元素。如果节点不为空,
234  *      则将该节点的左孩子和右孩子入队;如果节点为空,则查找后序出队的元素中是否全
235  *      是NULL,否则就不是完全二叉树
236  * */
237 Status IsCompleteBinaryTree(BiTree T){
238     Queue q = (Queue)malloc(sizeof(struct QueueNode));
239     if( !q )
240         return ERROR;
241     InitQueue(q);
242     BiTree node;
243     InitBinaryTreeNode(&node);
244     EnterQueue(q, T);
245     while( IsQueueEmpty(q) != OK ){
246         DeleteQueue(q, &node);
247         if( node != NULL ){
248             EnterQueue(q, node->lchild);
249             EnterQueue(q, node->rchild);
250         }
251         else{
252             while( IsQueueEmpty(q) != OK ){
253                 DeleteQueue(q, &node);
254                 if( node != NULL )
255                     return NO;
256             }
257         }
258     }
259     return YES;
260 }
261 int main(){
262     int level = 1;
263     BiTree BT;
264     InitBiTree(&BT);
265     if(IsTreeEmpty(BT))
266         printf("Binary is Empty!\n");
267     else
268         printf("Exist Element in Tree\n");
269     printf("Create Binary Tree by PreOrder: ");
270     CreateBiTree_PreOrder(&BT);
271     printf("PreOrder Traverse: \n");
272     PreOrderTraverse(BT,level);
273     printf("InOrder Traverse: \n");
274     InOrderTraverse(BT,level);
275     printf("PostOrder Traverse: \n");
276     PostOrderTraverse(BT,level);
277     printf("LevelOrder Traverse:  \n");
278     LevelOrderTraverse(BT);
279     printf("\nthe Depth of Binary is %d\n",BiTreeDepth(BT));
280 
281     if(IsCompleteBinaryTree(BT) == YES )
282         printf("Complete Binary Tree!\n");
283     else
284         printf("no-Complete Binary Tree!\n");
285     return 0;
286 }

转载于:https://www.cnblogs.com/robin-xu/p/5248669.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值