数据结构初阶之二叉树(三)

二叉树的接口函数

首先总结一下二叉树的各个接口函数:
二叉树的接口函数实现是明细要比前面学过的数据结构难的,所以这里全部列出来,然后给定代码,这些接口函数中,只有最后两个在前面的文章或者OJ当中还没出现:层序遍历和判断是否完全二叉树,其他的接口函数都已经出现过,下文撰写层序遍历和判断是否完全二叉树除了仅列出:

typedef char BTDataType;
 
typedef struct BinaryTreeNode
{
	BTDataType _data;
	struct BinaryTreeNode* _left;
	struct BinaryTreeNode* _right;
}BTNode;
 
// 通过前序遍历的数组"ABD##E#H##CF##G##"构建二叉树
BTNode* BinaryTreeCreate(BTDataType* a, int n, int* pi);
// 二叉树销毁
void BinaryTreeDestory(BTNode** root);
// 二叉树节点个数
int BinaryTreeSize(BTNode* root);
// 二叉树叶子节点个数
int BinaryTreeLeafSize(BTNode* root);
// 二叉树第k层节点个数
int BinaryTreeLevelKSize(BTNode* root, int k);
// 二叉树查找值为x的节点
BTNode* BinaryTreeFind(BTNode* root, BTDataType x);
// 二叉树前序遍历 
void BinaryTreePrevOrder(BTNode* root);
// 二叉树中序遍历
void BinaryTreeInOrder(BTNode* root);
// 二叉树后序遍历
void BinaryTreePostOrder(BTNode* root);
// 层序遍历
void BinaryTreeLevelOrder(BTNode* root);
// 判断二叉树是否是完全二叉树
int BinaryTreeComplete(BTNode* root);

通过前序遍历的数组"ABD##E#H##CF##G##"构建二叉树

BTNode* BinaryTreeCreate(BTDataType* a, int* pi);
BTNode* BuyNode(BTDataType x)
{
	BTNode* node = (BTNode*)malloc(sizeof(BTNode));
	assert(node);
	node->data = x;
	node->left = NULL;
	node->right = NULL;
	return node;
}

BTNode* BinaryTreeCreate(BTDataType* a int* pi);
{
    if(str[*pi]=='#')
    {
        (*pi)++;
        return NULL;
    }
    BTNode*root=BuyNode(str[(*pi)++]);
    root->left=CreateTree(str,pi);
    root->right=CreateTree(str,pi);
    return root;
}

int main()
{
    char str[100];
    scanf("%s",str);
    int i=0;
    BTNode*root=BinaryTreeCreate(str, &i);
    return 0;
}

 二叉树销毁

void BinaryTreeDestory(BTNode* root)
{
     if(root==NULL)
        return;
     BinaryTreeDestory(root->left);
     BinaryTreeDestory(root->right);
     free(root);
}

 二叉树节点个数

int BinaryTreeSize(BTNode* root)
{
     if(root==NULL)
       return 0;
     return BinaryTreeSize(root->left)+ BinaryTreeSize(root->right) + 1;
}

二叉树叶子节点个数

int BinaryTreeLeafSize(BTNode* root)
{


	if (root == NULL)
		return 0;
 
	if (root->left== NULL && root->right == NULL)
		return 1;
 
	return BinaryTreeLeafSize(root->left) + BinaryTreeLeafSize(root->right);

}

二叉树第k层节点个数

int BinaryTreeLevelKSize(BTNode* root, int k)
{
	assert(k >= 1);
	if (root == NULL)
		return 0;
 
	if (k == 1)
		return 1;
 
	return BinaryTreeLevelKSize(root->left, k - 1)
		+ BinaryTreeLevelKSize(root->right, k - 1);
}

二叉树查找值为x的节点

BTNode* BinaryTreeFind(BTNode* root, BTDataType x)
{
	if (root == NULL)
		return NULL;
 
	if (root->data == x)
		return root;
 
	BTNode* ret1 = BinaryTreeFind(root->left, x);
	if (ret1)
		return ret1;
 
	BTNode* ret2 = BinaryTreeFind(root->right, x);
	if (ret2)
		return ret2;
 
	return NULL;
}

二叉树前序遍历 

int TreeSize(struct TreeNode*root)
{
    return root==NULL?0:TreeSize(root->left)+TreeSize(root->right)+1;
}
void preorder(struct TreeNode* root,int *a,int* pi)
{
    if(root==NULL)
    return ;
    a[(*pi)++]=root->val;
    preorder(root->left,a,pi);
    preorder(root->right,a,pi);
}

int* preorderTraversal(struct TreeNode* root, int* returnSize){
    *returnSize=TreeSize(root);
    int *a=(int *)malloc(*returnSize*sizeof(int));
    int i=0;
    preorder(root,a,&i);
    return a;
}

二叉树中序遍历

int TreeSize(struct TreeNode*root)
{
    return root==NULL?0:TreeSize(root->left)+TreeSize(root->right)+1;
}
void InOrder(struct TreeNode* root,int*a,int* pi)
{
    if(root==NULL)
    return ;
    
    InOrder(root->left,a,pi);
    a[(*pi)++]=root->val;
    InOrder(root->right,a,pi);
}


int* inorderTraversal(struct TreeNode* root, int* returnSize){
    * returnSize=TreeSize(root);
    int* a=(int*)malloc(sizeof(int)**returnSize);
    int i=0;
    InOrder(root,a,&i);
    return a;
}

二叉树后序遍历

int TreeSize(struct TreeNode*root)
{
    return root==NULL?0:TreeSize(root->left)+TreeSize(root->right)+1;
}
void InOrder(struct TreeNode* root,int*a,int* pi)
{
    if(root==NULL)
    return ;
    
    InOrder(root->left,a,pi);
    
    InOrder(root->right,a,pi);
    a[(*pi)++]=root->val;
}


int* postorderTraversal(struct TreeNode* root, int* returnSize){
    * returnSize=TreeSize(root);
    int* a=(int*)malloc(sizeof(int)**returnSize);
    int i=0;
    InOrder(root,a,&i);
    return a;
}

以上这三个都是一个道理。

层序遍历,这是一种广度优先遍历的方式

思路:利用队列来做,下图举例子

数据结构初阶之二叉树(三)_第1张图片

 创建一个队列,先进1,保存队头,再出1,然后2和3进,保存队头2,出2,进4和5,再保存队头3,出3,保存队头4.......直到遍历完成。

void BinaryTreeLevelOrder(BTNode* root)
{
	Queue q;
	QueueInit(&q);
	if (root)
	{
		QueuePush(&q, root);

	}
	while (!QueueEmpty(&q))
	{
		BTNode* front = QueueFront(&q);
		printf("%d ",front->data);
		QueuePop(&q);
		if (front -> left)
		{
			QueuePush(&q, front->left);
		}
		if (front -> left)
		{
			QueuePush(&q, front->right);
		}
	}
	printf("\n");
	QueueDestroy(&q);
}

判断二叉树是否是完全二叉树

这个其实就是再层序遍历上来做,如果队列的front出现空,且后续层序遍历全是空,则是完全二叉树,若front出现空之后,后续有非空元素出现,则不是完全二叉树。

// 判断二叉树是否是完全二叉树
//核心思路:层序遍历时,把空也入队列。
//完全二叉树,非空是连续
//不是完全二叉树,非空不是连续
bool BinaryTreeComplete(BTNode* root)
{
    Queue q;
    QueueInit(&q);
    if(root)//先入队根节点
    {
        QueuePush(&q,root);
    }
    while(!QueueEmpty(&q))
    {
        BTNode* front = QueueFront(&q);//取队头,将它保存起来
        QueuePop(&q);//出队
        if(front==NULL)
        {
            break;//遇到空就跳出循环
        }
        //不管是不是NULL都入队
        QueuePush(&q,front->left);
        QueuePush(&q,front->right); 
    }
    // 出到空以后,队列中全是空,就是完全二叉树
	// 还有非空,就不是完全二叉树
    while(!QueueEmpty(&q))
    {
        BTNode* front = QueueFront(&q);//取队头,将它保存起来
        QueuePop(&q);//出队
        if(front)
        {
            QueueDestory(&q);
            return false;
        }
    }
    //走到这里说明队列后面是连续的空,故是完全二叉树
    QueueDestory(&q);
    return true;
}


 

你可能感兴趣的:(数据结构初阶,数据结构,算法,排序算法)