数和二叉树,查找算法总结

一.思维导图

二.重要概念笔记

1.树

1.n=0 的树称为空树;对于n>0的任意非空树T有:

-有且仅有一个特殊的结点称为树的根(Root)结点,根没有前驱结点
-若n>1,则除根结点外,其余结点被分成了m(m>0)个互不相交的集合T 1 ,T 2 ,…,T m ,其中每一个集合T i (1≤i≤m)本身又是一棵树。树T 1 ,T 2 ,…,T m
称为这棵树的子树

2.树的特点

-树的根结点没有前驱结点,除根结点之外的所有结点有且只有一个前驱结点
-树中的所有结点都可以有零个或多个后继结点

2.二叉树的遍历

1.前中后序遍历

以前序遍历为例

void preorder(node *root) {
		if( root == NULL)
			return; //到达空树,递归边界(前中后一样)
		printf("%d\n", root -> data); //访问根节点
		//访问左子树
		preorder(root -> lchild);
		//访问右子树
		preorder(root -> rchild);	
}

2.层序遍历

从树根自顶向下,且同层从左到右(需要用到队列)

void LayerOrder(node* root) {
		//存放node型变量的地址,可以直接对原元素进行修改
		queue<node*> q;
		q.push(root); //从根节点地址入队
		while( ! q.empty ( ) ){
				node* now = q.front(); //取出队首元素
				q.pop();
				printf("%d",now -> data); //访问队首元素
				if( now -> lchild ! = NULL)  {
						
						//升级版 
						//now -> lchild -> layer = now -> layer +1;
						//表示左孩子层号为右孩子加1
						q.push(now -> lchild) ; //左子树非空
				}
				if( now -> rchild ! = NULL)  { 
				        //升级版同上
						q.push(now -> rchild) ; //右子树非空
				}
		}
}

3.Eg: 已知先序和中序序列,要求构建一棵二叉树

node* create(int preL, int preR, int inL, int inR){
	// 先序序列区间[preL, preR], 中序序列区间[inL, inR]
	if(preL > preR) {
		return; //递归边界
	}
	node* root = new node;//新建一个节点
	root -> data = pre[preL]; //先序序列第一个值是根节点
    for(int i = inL; i <= inR; i++){
    	if(pre[preL] == in[i])
    		break; //在中序序列中找到与根节点的值相等的,确定分界线
    } 
    int leftin = i - inL;
    root -> lchild = create(preL+1, preL+leftin, inL, i-1);
    root -> rchild = create(preL+leftin+1, preR, i+1, inR);
    return root;
}

4.二叉排序树的构建,插入,查找与删除

InsertBST(T, key) {
    if (T为空) {
        创建T;
        T->data = key;
        T的左孩子 = T的右孩子 = 空;
        return;
    }
    else if (T->data = key)
        return;
    else if (key < T->data)
        InsertBST(T->lchild, key);
    else if (key > T->data)
        InsertBST(T->rchild, key);
}

int InsertBST(BTree& BT, int k) {
    if (BT == NULL) {
        BT = new BTNode;
        BT->data = k;
        BT->lchild = BT->rchild = NULL;
        return 1;
    }
    else if (BT->data == k) {
        return 0;
    }
    else if (k < BT->data) {
        return InsertBST(BT->lchild, k);
    }
    else
        return InsertBST(BT->rchild, k);
}
BTree SearchBST(BTree BT, int k) {
    if (BT == NULL || BT->data == k)
        return BT;
    if (k < BT->data)
        return SearchBST(BT->lchild, k);
    else
        return SearchBST(BT->rchild, k);
}
void DeleteBST(BTree & BT) {
    BTree q, s;
    if (BT->lchild == NULL) {
        q = BT;
        BT = BT->rchild;
        delete q;
    }
    else if (BT->rchild == NULL) {
        q = BT;
        BT = BT->lchild;
        delete q;
    }
    else {
        q = BT;
        s = BT->lchild;
        while (s->rchild) {
            q = s;
            s = s->rchild;
        }
        BT->data = s->data;
        if (q == BT)
            BT->lchild = s->lchild;
        else
            q->rchild = s->lchild;
        delete s;
    }
}

3.树的种类(概念)

1.无序树:树中任意节点的子节点之间没有顺序关系,这种树称为无序树,也称为自由树

2.有序树:树中任意节点的子节点之间有顺序关系,这种树称为有序树

3.二叉树:每个节点最多含有两个子树的树称为二叉树

-完全二叉树:对于一颗二叉树,假设其深度为d(d>1)。除了第d层外,其它各层的节点数目均已达最大值,且第d层所有节点从左向右连续地紧密排列,这样的二叉树被称为完全二叉树;【倒数第一层不是倒数第二层的二倍,尚缺N个节点】
-满二叉树:对于上述的完全二叉树,如果去掉其第d层的所有节点,那么剩下的部分就构成一个满二叉树(此时该满二叉树的深度为d-1);【倒数第一层是倒数第二层的二倍】

4.哈夫曼树:带权路径最短的二叉树称为哈夫曼树或最优二叉树

5.B树:【每一层数据大小有序】

4.查找

1.二分法查找

void BinSearch(SeList r,int n,KeyType k)
{
	int low = 0, high = n - 1, mid;
	while (low <= high)
	{
		mid = (low + high) / 2;
		if (r[mid].key == k)
			return mid + 1;
		if (r[mid].key > k)
			high = mid - 1;
		else
			low = mid + 1;
	}
	return 0;
}

三.疑难问题

1.二叉树叶子结点带权路径长度和



代码

#include<iostream>
#include<string>
using namespace std;
typedef struct BTNode {
    char data;
    struct BTNode *lchild, *rchild;
}BTNode, * BTree;
void CreateBtree(string S, BTree& BT, int i);//建树
int SumTree(BTree q, int i);//计算
int main() {
    BTree q;
    string s;
    cin>>s;
    CreateBtree(s, q,1);
    cout << SumTree(q, 0);
}
void CreateBtree(string S, BTree& BT, int i) {
    if (i >= S.size()) {
        BT = NULL;
        return;
    }
    if (S[i] == '#') {
        BT = NULL;
        return;
    }
    BT = new BTNode;
    BT->data = S[i];
    CreateBtree(S, BT->lchild, 2 * i);
    CreateBtree(S, BT->rchild, 2 * i + 1);
}
int SumTree(BTree q, int i) {
    if (q == NULL)return 0;
    if (q->lchild == NULL && q->rchild == NULL) {
        return (q->data-48) * i;
    }
    i++;
    return SumTree(q->lchild, i) + SumTree(q->rchild, i);
}
posted @ 2020-04-26 15:39  祖国庇佑我  阅读(177)  评论(0编辑  收藏  举报