c实现链式存储二叉树和二叉树遍历

#1二叉树

    (1) 二叉树是一种树型结构

    (2) 二叉树的特点:每个结点至多只有两棵子树,并且有左右子树之分。

可以使用顺序存储或链式存储二叉树

#1.1顺序存储二叉树

#define MAX_BINARYTREE_SIZE 100 //最多结点
typedef TElemType SqBiTree[MAX_BINARYTREE_SIZE]; //SqBiTree[0]为根结点
SqBiTree bt;

用第编号i表示指定结点,若i=1即为根结点SqBiTree[i-1]即SqBiTree[0]存储

指定i结点,i > 1,则parent(i) = [i/2]  ,即i/2后向下取整。

                               lchild(i) = 2*i    

                               rchild(i) = 2*i +1

所以我们以SqBiTree[i-1]存储第i个结点

               以SqBiTree[2*i - 1]存储第i个结点的左子结点

               以SqBiTree[2*i]存储第i个结点的右子结点

分析如图 1所示。

#1.2链式存储二叉树

这里用c实现链式存储二叉树,即二叉链表

二叉树的结点由一个数据元素和分别指向其左右子树的两个分支构成。

实现代码如下:

/*
 ============================================================================
 Name        : BinaryTreeC.c
 Author      : lingo
 Version     :
 Copyright   : Your copyright notice
 Description : Hello World in C, Ansi-style
 ============================================================================
 */

#include <stdio.h>
#include <stdlib.h>
#include <malloc.h>
/**
 * 结构体写法  左边其实等于右边可以看出BiTNode,BiTree为后声明的名称,
 * 所以定义结构时不能使用 BiTNode和BiTree ,但结构体前typedef则可使用
 *
	 typedef struct tNode{           struct tNode{
		TElemType data;					TElemType data;
		struct tNode* lchird;			struct tNode* lchird;
		struct tNode* rchird;			struct tNode* rchird;
	 }BiTNode,*BiTree;				 };
									 typedef struct tNode BiTNode;
									 typedef struct tNode* BiTree;

 */
/**
 *  结构体写法2
	typedef struct tNode BiTNode;
	typedef struct tNode* BiTree;
	struct tNode{
	TElemType data;
	BiTNode* lchird;
	BiTNode* rchird;
	};

 */
typedef int Status;//函数结果状态
typedef int TElemType;
typedef struct tNode{
	TElemType data;
	struct tNode *lchird,*rchird;
}BiTNode,*BiTree;
//创建一个结点,并返回一个指向该结点的指针
BiTNode * newBiTNode(int data){
	BiTNode *btnode = (BiTNode *)malloc(sizeof(BiTNode));
	btnode->data = data;
	btnode->lchird = NULL;
	btnode->rchird = NULL;
	return btnode;
}

void printBiTree(BiTree T){
	if(T){
		printf("%d\n",T->data);
	}
	if(T->lchird){
		printf("%d,his lchird: ",T->data);
		printBiTree(T->lchird);
	}
	if(T->rchird){
		printf("%d,his rchird: ",T->data);
		printBiTree(T->rchird);
	}
}

void DestoryBiTree(BiTree &T){
	if(T != NULL){
		DestoryBiTree(T->lchird);
		DestoryBiTree(T->rchird);
		free(T);
	}
}



初始化如下二叉树:

mian函数:

int main(int arg,char *argv[]) {
	BiTree btroot = NULL;
	btroot = newBiTNode(1);  //根结点
	btroot->lchird = newBiTNode(2); 
	btroot->rchird = newBiTNode(3);
	btroot->lchird->lchird = newBiTNode(4);
	btroot->lchird->rchird = newBiTNode(5);
	btroot->rchird->lchird = newBiTNode(6);

	printBiTree(btroot);

	DestoryBiTree(btroot);
	return 0;
}

结果:

1
1,his lchird: 2
2,his lchird: 4
2,his rchird: 5
1,his rchird: 3
3,his lchird: 6

若一颗二叉树如下所示:

在二叉树的遍历中有,

1. 先(根)序遍历,结果为: 1 245 36

2.中(根)序遍历 ,结果为: 425 1  63

3.后(根)序遍历 ,结果为: 452 63  1

遍历实现如下:

Status Visit(TElemType e){
	printf("%d",e);
	return OK;
}
// 先序遍历
Status PreOrderTraverse(BiTree T,Status (* Visit)(TElemType)){
	if(T){
		Visit(T->data);
		PreOrderTraverse(T->lchird,Visit);
		PreOrderTraverse(T->rchird,Visit);
	}
	return OK;
}
Status InOrderTraverse(BiTree T,Status (* Visit)(TElemType)){
	if(T){
			InOrderTraverse(T->lchird,Visit);
			Visit(T->data);
			InOrderTraverse(T->rchird,Visit);
		}
	return OK;
}
Status PostOrderTraverse(BiTree T,Status (* Visit)(TElemType)){
	if(T){
			PostOrderTraverse(T->lchird,Visit);
			PostOrderTraverse(T->rchird,Visit);
			Visit(T->data);
		}
	return OK;
}

 测试代码:

int main(int arg,char *argv[]) {
	BiTree btroot = NULL;
	btroot = newBiTNode(1);
	btroot->lchird = newBiTNode(2);
	btroot->rchird = newBiTNode(3);
	btroot->lchird->lchird = newBiTNode(4);
	btroot->lchird->rchird = newBiTNode(5);
	btroot->rchird->lchird = newBiTNode(6);
	printf("先序遍历:");
	PreOrderTraverse(btroot,*Visit);
	printf("\n中序遍历:");
	InOrderTraverse(btroot,*Visit);
	printf("\n后序遍历:");
	PostOrderTraverse(btroot,*Visit);
	DestoryBiTree(btroot);
	return 0;
}

 

层次遍历:非叶子结点左或右结点为空输出NULL

层次遍历结果:1 2 3 4 5 6 

若结点4删除,则遍历结果:1 2 3 5 6 

Status LevelOrderTraverse(BiTree T){
	SqQueueP sq;
	InitQueue(sq);
	EnQueue(sq, T);
	while(!QueueEmpty(sq)){
		BiTNode* temp = DeQueue(sq);
		if(temp) {
			printf(" %d ",temp->data);
			if(!temp->lchird&&!temp->rchird){ //若为叶子结点不存储左右子结点
				continue;
			}else{
				EnQueue(sq, temp->lchird);
				EnQueue(sq, temp->rchird);
			}
		}
	}
	return OK;
}

若是左或右子结点为空以NULL并输出存在则修改遍历算法中指针判断如下:

if(temp) {
	printf(" %d ",temp->data);
        EnQueue(sq, temp->lchird);
	EnQueue(sq, temp->rchird);
}
else printf(" NULL ");

层次遍历结果如下:

层次遍历结果:1 2 3 4 5 6 NULL

层次遍历结果:1  2  3  NULL  NULL  6  NULL  NULL  NULL 

 

 

                              图1 顺序存储二叉树思路

 

 

 

 

 

 

 

 

  • 0
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值