树的总结

思维导图

重要概念

 

二叉树的性质

性质1 :在二叉树的第 i 层上至多有2i-1 个结 点(i≥1)。

性质2:深度为 k 的二叉树上至多含 2k-1 个结 点(k≥1)。

性质3:对任何一棵二叉树,若它含有n0 个叶子 结点、n2 个度为2的结点,则必存在关系式:n0 = n2+1。

 

B-树

 

性质:

1.每个节点至多m个孩子节点(至多有m-1个关键字) 。

2.除根节点外,其他节点至少有m/2个孩子节点(即 至少有m/2-1个关键字)。

3.若根节点不是叶子节点,根节点至少两个孩子节点。

 

插入:

关键字 插入的位置必定在最下层的非叶结点,插入后,该结点的关键字个数n<m,不修改指针,插入后,该结点的关键字个数 n=m,则需进行 “结点分裂”,令 s = m/2,在原结点中保留 (A0,K1,…… , Ks-1,As-1);建新结点(As, Ks+1,…… ,Kn,An);将(Ks, p)插入双亲结点,若双亲为空,则建新的根结点。

 

二叉树中序遍历的非递归算法的代码

void LevelTraversal(queue<BiTree>& que, BiTree T)
{
	int count = 0;
	que.push(T);

	while (!que.empty())
	{
		if (que.front()->lchild) {
			que.push(que.front()->lchild);
		}
		if (que.front()->rchild) {
			que.push(que.front()->rchild);
		}

		if (count == 0) {
			cout << que.front()->data;
			count = 1;
		}
		else {
			cout << " " << que.front()->data;
		}
		que.pop();
	}

}

 

求二叉树树的高度

int GetHeight(BinTree BT)
{
	int LH, RH;
	if (!BT)
		return 0;
	else
	{
		LH = GetHeight(BT->Left);
		RH = GetHeight(BT->Right);
		return LH > RH ? ++LH : ++RH;
	}
}

 

二叉树的层次遍历

void LevelTraversal(BiTree T)
{
	int count = 0;
	queue<BiTree> que;
	que.push(T);

	while (!que.empty())
	{
		if (que.front()->lchild) {
			que.push(que.front()->lchild);
		}
		if (que.front()->rchild) {
			que.push(que.front()->rchild);
		}

		if (count == 0) {
			cout << que.front()->data;
			count = 1;
		}
		else {
			cout << " " << que.front()->data;
		}
		que.pop();
	}

}

 

二叉排序树建立,查找,插入,删除伪代码及代码实现

#include <iostream>
using namespace std;

#include <stdio.h>

typedef struct BiTNode
{
	int data;
	struct BiTNode* lchild, * rchild;
}BiTNode, * BiTree;

void Delete(BiTNode*& p);
void Delete1(BiTNode* p, BiTNode* &r);

/*SearchBst(T, key) {

	if (T为空 || T->data等于key)
		return T;
	if (T->data小于key)
		SearchBst(T->lchild, key);
	else
		SearchBst(T->rchild, key);

}*/

BiTNode*SearchBST(BiTNode *T, int key)
{
	if (T==NULL|| T->data == key)
		return T;
	if (T->data<key)
		SearchBST(T->lchild, key);
	else
		SearchBST(T->rchild, key);
}

/*InsertBST(T, key) {

	if (T等于空) {
		T->data == key;
		T->lchild == T->rchild = NULL;
	}
	else {
		if (T->data等于key)return;
		else {
			if (key小于T->data) {
				插入左子树
					InsertBST(T->lchild, key);
			}
			else 插入右子树
				InsertBST(T->rchild, key);
		}

}*/

void InsertBST(BiTNode* &T, int key)//建立二叉排序树
{
	if (T == NULL) {
		T = new BiTNode;
		T->data = key;
		T->lchild = T->rchild = NULL;

	}
	else {
		if (T->data == key)return;
		else if (key < T->data) {
			return InsertBST(T->lchild, key);
		}
		else {
			return InsertBST(T->rchild, key);
		}
	}

}

/*CreateBST(T)
{
	int a[100];
	int i=0;
	BiTree* T = NULL;
	char ch;

	do {
		i++;
		读入数字到数组a中
		插入到二叉树中

	} while (读入一个字符判断是否到结尾);

	return T;
}*/

BiTNode  *CreateBST()
{
	int a[100];
	int i=-1;
	BiTNode* T = NULL;

	char ch;

	do {
		i++;
		cin >> a[i];
		InsertBST(T, a[i]);

	} while ((ch = getchar()) != '\n');

	return T;
}

/*DeleteBST(T, key)
{
	if (T为空) {
		return 0;
	}
	else {
		if (key小于T->data) DeleteBST(T->lchild, key);
		递归在左子树中删除key的节点
		else if (key小于T->data) DeleteBST(T->rchild, key);
		递归在右子树中删除key的节点
		else {
			进入Delete(T)删除节点
				return 1;
		}
	}
}*/

int  DeleteBST(BiTNode* &T, int key)
{
	if (T==NULL) {
		return 0;
	}
	else {
		if (key < T->data) {
			return DeleteBST(T->lchild, key);
		}
		else {
			if (key > T->data) {
				return DeleteBST(T->rchild, key);
			}
			else {
				Delete(T);
				return 1;
			}
		}
	}
}

/*Delete(p)
{
	定义一个节点q
		if (p的右子树为空) {
			q = p;
			p等于p的左子树
				free(p);
		}
		else {
			if (p的左子树为空) {
				q = p;
				p等于p的右子树
					free(q);
			}
			else {
				既有左右子树,进入Delete1(p, p->lchild)函数
			}
		}
}*/

void Delete(BiTNode*& p)
{
	BiTNode* q;
	if (p->rchild==NULL) {
		q = p;
		p = p->lchild;
		free(q);
	}
	else {
		if (p->lchild == NULL) {
			q = p;
			p = p->rchild;
			free(q);
		}
		else {
			Delete1(p, p->lchild);
		}
	}
}

/*Delete1(p, r)
{
	定义节点q
		if (r右子树不为空) {
			接着查找p的左子树的最右下节点Delete1(p, r->rchild);
		}
		else {
			p->data = r->data;
			q = r;
			r等于r的左子树
				free(q);
		}
}*/

void Delete1(BiTNode* p, BiTNode* &r)
{
	BiTNode* q;
	if (r->rchild != NULL) {
		Delete1(p, r->rchild);
	}
	else {
		p->data = r->data;
		q = r;
		r = r->lchild;
		free(q);
	}
}

void InOrderTraverse(BiTree T)//中序遍历
{
	if (T == NULL)
		return;
	InOrderTraverse(T->lchild);
	cout << T->data << " ";
	InOrderTraverse(T->rchild);
}

int main()
{
	BiTree BST = CreateBST();

	cout << "中序遍历:";
	InOrderTraverse(BST);
	cout << endl;

	cout << "请输入你要清除的数字" << endl;

	int n;
	cin >> n;

	int cont = DeleteBST(BST, n);

	if (cont == 0) {
		cout << "数字不存在" << endl;
	}
	else {
		cout << "清除成功" << endl;
	}

	cout << "中序遍历:";
	InOrderTraverse(BST);

	return 0;
}

 

疑难问题及解决方案

 

根据后序和中序遍历输出先序遍历(PTA)

 
由题意,必须先理解后序遍历和中序遍历结果对应的二叉树是怎么样,先把根确定,在确定根的左子树和右子树,然后进去根的左子树,右子树,在确定左子树和右子树的样子,从上向下确定整个二叉树。
 

#include<iostream>
using namespace std;

int in[31],post[31];

typedef struct BiTNode{
	int data;
	struct BiTNode *lchild;
	struct BiTNode *rchild;
}BiTNode,*BiTree;

BiTree Build(int *in,int *post,int n)
{
	if(n <= 0)
		return NULL;

	int *p = in;

	while(p){
		if(*p == *(post + n - 1))
			break;
		p++;
	}

	BiTree T = new BiTNode;
	T->data = *p;

	int len = p - in;
	T->lchild = Build(in,post,len);
	T->rchild = Build(p + 1,post + len,n - len - 1);

	return T; 
}

void PreOrder(BiTree T){

	if(T){
		printf(" %d",T->data);
		PreOrder(T->lchild);
		PreOrder(T->rchild);
	}

	return;
}

int main(){

	int n;
	BiTree T;
	scanf("%d",&n);

	for(int i = 0;i < n;i++)
		scanf("%d",&post[i]);

	for(int i = 0;i < n;i++)
		scanf("%d",&in[i]);

	T = Build(in,post,n);
	printf("Preorder:");
	PreOrder(T);
    
	return 0;
}

 

疑难问题

1.B-树和B+树怎么创建?

2.有没有更好的树的算法?

posted @ 2020-04-26 11:23  违久(丁鸿沛)  阅读(312)  评论(0编辑  收藏  举报