欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

二叉树

程序员文章站 2022-03-14 18:41:39
...

二叉树

二叉树是只有左右结点的特殊的树,可以分为满二叉树和完全二叉树(完全二叉树是满二叉树的特殊形式)
结点个数 = 边的个数 + 1
对于完全二叉树而言 结点个数:2^n----->高度为log(n)

二叉树的基本操作

二叉树的创建

根据前序遍历创建


typedef struct Node {
 char val;
 struct Node *left;
 struct Node *right;
} Node;
typedef struct ReturnType {
 Node * root; // 创建好树的根节点
 int used;  // 创建树过程中用掉的值个数
} ReturnType;
ReturnType createTree(char preorder[], int size) {
 char rootValue = preorder[0];
 if (rootValue == '#') {
  ReturnType returnValue;
  returnValue.root = NULL;
  returnValue.used = 1;
  return returnValue;
  }
 Node * root = (Node *)malloc(sizeof(Node));
 root->val = rootValue;
ReturnType left = createTree(preorder + 1, size - 1);
ReturnType right = createTree(preorder + 1 + left.used,size - 1 - left.used);
  root->left = left.root;
  root->right = right.root;
  
  ReturnType returnValue;
  returnValue.root = root;
  returnValue.used = +left.used+right.used;
  
return returnValue;
}

二叉树的遍历

前序遍历:首先遍历根节点,再遍历左右结点(递归/非递归实现)
中序遍历:遍历左结点后遍历根节点,最后遍历右结点(递归/非递归)
后序遍历:先遍历左右结点,再遍历根节点(递归/非递归)
非递归遍历需要使用栈。

二叉树

//递归遍历
//前序遍历
void PreorderTraval(Node* root)
{
 printf("%c ", root->val);
 PreorderTraval(root->left);
 PreorderTraval(root->right);
}
//中序遍历
void inorderTraval(Node* root)
{
 PreorderTraval(root->left);
 printf("%c ", root->val);
 PreorderTraval(root->right);
}
//后序遍历
void postorderTraval(Node* root)
{
 PreorderTraval(root->left);
 PreorderTraval(root->right);
 printf("%c ", root->val);
}
//非递归
//前序遍历
void preorder(Node* root)
{
 Node* cur = root;
 Node* top = NULL;
 stack S;
 stackInit(&S);
 while (cur || stackempty(&S)!=0)
 {
  while (cur)
  {
   printf("%c ", cur->val);
   stackpush(&S, cur);
   cur = cur->left;
	}
  top = stacktop(&S);
  stackpop(&S);
  cur = cur->right;
}
//中序遍历
void inorder(Node* root)
{
 Node* cur = root;
 Node* top = NULL;
 stack S;
 stackInit(&S);
 while (cur || stackempty(&S)!=0)
 {
  while (cur)
  {
   stackpush(&S, cur);
   cur = cur->left;
 }
  top = stacktop(&S);
  printf("%c ", top->val);
  stackpop(&S);
  cur=top->right;
  }
 
 //后序遍历
void inorder(Node* root)
{
 Node* cur = root;
 Node* top = NULL;
 Node* prev = NULL;
 stack S;
 stackInit(&S);
 while (cur || stackempty(&S)!=0)
 {
  while (cur)
  {
   stackpush(&S, cur);
   cur = cur->left;
   }
   top=stacktop(&S);
   if(top->right==NULL||top->right==prev)
   {
	printf("%c ",top->val);
	prev = top;
	stackpop(&S);
   }
   else
   cur = cur->right;
   }
}
//按层遍历
#include<queue>
void levelorder(Node* root)
{
	if(root==NULL)
		return;
	std::queue<Node*>   q;
	q.push(root);
	if(!q.empty())
	{
		Node* front = q.front();
		q,pop();
		printf("%c ",front->val);
		if(front->left != NULL)
			q.push(front->left);
		if(front->right != NULL)
			q.push(front->right);

	}
}

二叉树的结点数

递归求左右结点数,总结点数为左右结点数加1。

int GetNodeCount(Node* root)
{
 if (root == NULL)
  return;
 int left = GetNodeCount(root->left);
 int right = GetNodeCount(root->right);
 return left + right + 1;
}

二叉树的高度

递归:左右子树较高的加1。

int Mymax(int a,int b)
{
	return a>b?a:b;
}
int Height(Node* root)
{
 if (root == NULL)
  return 0;
 int left = Height(root->left);
 int right = Height(root->right);
 return Mymax(left, right) + 1;
 }

获取叶子结点

int GetLeafNodeCount(Node* root)
{
 if (root == NULL)
  return 0;
 if (root->right == NULL&&root->left == NULL)
  return 1;
 int left = GetLeafNodeCount(root->left);
 int right = GetLeafNodeCount(root->right);
 return right + left;
 }

获取第k层结点个数

利用递归求第k–,我们仅能知道第一层结点个数是1。

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

销毁二叉树

使用递归的方法从下往上销毁

void DestroyBinTree(Node* root)
{
 if (root)
 {
  DestroyBinTree(root->left);
  DestroyBinTree(root->right);
  free(root);
  }