前端-数据结构第四天-树

5.1 Binary Tree 二叉树

Binary Tree:each node can have at most 2 children
Strict/Proper binary tree: each node can have either 2 or 0 children
Complete Binary tree:all levels except possibly the last are completely filled and all nodes are as left as possible

5.1.1 height of tree
- min-height=[log2 n] O(log2 n);max-height=n-1 O(n);
5.1.2 binary search Tree
        Array 数组已经满,复制的成本是O(n);Linked List   BST

search(x) O(n); O(n); O(logn)
Insert(x) O(1); O(1); O(logn)
remove(x) O(n); O(n); O(logn)

5.1.3二分查找法 O(logn)

二叉搜索树 Olgn
平衡树:通过保持二叉搜索树来避免二叉搜索树搜索时间复杂度为O(n);
二叉完美树

二叉搜索树的实现 binary search tree- Implementation in c/c++

#include<iostream>
using namespace std;
struct BstNode{
    int data;
    BstNode* left;
    BstNode* right;
};
 BstNode* GetNewNode(int data){
     BstNode* newNode = new BstNode();
     newNode->data = data;
     newNode->left = NULL;
     newNode->right = NULL;

 }
//----------BstNode**方式start--------
 //BstNode** rootPtr 传的是root的地址
void Insert(BstNode** root,int data){
    //*root 获取root的值,使用*操作符来访问main中的root的值
    if(*root == NULL)
    {
        *root = GetNewNode(data);
    }
};

int main(){
    //root 是局部变量
    BstNode* root = NULL;
    Insert(&root,15);
    Insert(&root,10);
    Insert(&root,20);
}
//----------------------end
//-------------BstNode*方式start
BstNode* Insert(BstNode* root,int data){
    if(root == NULL)
    {
        root = GetNewNode(data);
    }
    else if(data <= root->data){
        root->left = Insert(root->left,data);
    }
    else{
        root->right = Insert(root->right,data);
    }
    return root;
};
bool Search(BstNode* root,int data){
    if(root == NULL)return false;
    else if(root->data == data)return true;
    else if(data <= root->data)return Search(root->left,data);
    else return Search(root->right,data);
}
int main(){
    //root 是局部变量
    BstNode* root = NULL;
    root = Insert(&root,15);
    root = Insert(&root,10);
    root = Insert(&root,20);
    int number;
    cout<<"enter number be searched\n";
    cin>>number;
    if(Search(root,number)== true)cout<<"found\n";
    else cout<<"not found\n";
}
//-------------BstNode*方式end

BST implementation in c/c++ - Part2

Cde(Text)代码段:存储程序指令
Static/Global:存放全局变量
Stack:栈,程序完成,自动释放
Heap:堆,动态内存,free store,可以控制堆内存的分配或者回收

Find min and max element in a BST

struct BsNode {
    int data;
    BsNode* left;
    BsNode* right;
}
int FindMin(BsNode* root){
    if(root == NULL){
        cout<<"error: tree is empty";
        return -1;
    }
    while(root->left != NULL){
        root = root->left;
    }
    //search in left subtress
    return FindMin(root->left);
}

find height of a binary tree

height of a node:
Number of edges in longest
path from the node to a leaf node
height of tree = Height of root
Depth of a node = 从根节点到该节点的边数

FindHeight(root){
    if(root == NULL) return -1;
    leftHeight<-FindHeight(root->left);
    rightHeight<-FindHeight(root->right)
    return max(leftHeight,rightHeight)+1
}

binary Tree Traversal 二叉树遍历,广度优先,深度优先

深度优先遍历-先序变量

先根次序遍历按照“根结点 > 左孩子 > 右孩子”的顺序进行访问。

// 递归实现-先根递归遍历。
void preOrderRecursion(BinaryTreeNode* root) {
	if(root==NULL) return;
	cout<< " " << root->data;
	preOrderRecursion(root->m_pLeft);
	preOrderRecursion(root->m_pRight);
}
// 先序非递归遍历,需要使用栈
void preOrderStack(BinaryTreeNode* root) {
	if(root==NULL) return;
	
	stack<BinaryTreeNode*> stack;
	stack.push(root);
	BinaryTreeNode* cur=NULL;
	while(!stack.empty()) {
		cur=stack.top();
		cout<<" "<<cur->data; //visit
		stack.pop();
		if(cur->m_pRight!=NULL) {
			stack.push(cur->m_pRight);
		}
		if(cur->m_pLeft!=NULL) {
			stack.push(cur->m_pLeft);
		}
	}
}
深度优先遍历-中序遍历

中序遍历按照“左孩子 > 根结点 > 右孩子”的顺序进行访问。

// 中序递归遍历。
void midOrderRecursion(BinaryTreeNode* root){
	if(root==NULL) return;
	midOrderRecursion(root->m_pLeft);
	cout<<" "<<root->data;   //visit
	midOrderRecursion(root->m_pRight);
}
// 中根非递归遍历,需要使用栈
void midOrderStack(BinaryTreeNode* root) {
	if(root==NULL) return; 
	
	stack<BinaryTreeNode*> stack;
	BinaryTreeNode* cur=root;
	while(!stack.empty() || cur!=NULL) {
        while(cur) {  
            stack.push(cur);  
            cur=cur->m_pLeft;  
        }  
        cur=stack.top();  
		cout<<" "<<cur->data;   //visit
        stack.pop();  
        cur=cur->m_pRight;  
    }
}
深度优先遍历-后序遍历

后序遍历按照“左孩子 > 右孩子 > 根结点”的顺序进行访问。

// 后根递归遍历
void postOrderRecursion(BinaryTreeNode* root) {
	if(root==NULL) return;
	postOrderRecursion(root->m_pLeft);
	postOrderRecursion(root->m_pRight);
	cout << " " << root->data;
}
// 非递归后序遍历,版本1
void postOrderStack1(BinaryTreeNode* root) {
	if(root==NULL) return; 
	stack<pair<BinaryTreeNode*, bool>> s;
    pair<BinaryTreeNode*,bool> cur=make_pair(root,true);
    while(cur.first!=NULL||!s.empty()) {
     	//沿左子树一直往下搜索,直至出现没有左子树的结点
        while(cur.first!=NULL) {
            s.push(cur);
			cur=make_pair(cur.first->m_pLeft,true);
        }
        if(!s.empty()) {
        	//表示是第一次出现在栈顶
            if(s.top().second==true) { 
                s.top().second=false;
                cur=make_pair(s.top().first->m_pRight,true); //将当前节点的右节点入栈
            } else {
            	// 第二次出现在栈顶 
                cout << s.top().first->data << " ";
                s.pop();
            }
        }
    }
}

广度优先遍历

广度优先周游的方式是按层次从上到下,从左到右的逐层访问,不难想到,可以利用一个队列来实现。基本思想如下:
(1)首先把二叉树的根节点送入队列;
(2)队首的节点出队列并访问之,然后把它的右子节点和左子节点分别入队列;
(3)重复上面两步操作,直至队空。

// 广度优先遍历二叉树,使用队列实现
void breadthFirstOrder(BinaryTreeNode* root) {
	if(root==NULL) return;
	queue<BinaryTreeNode*> queue;
	queue.push(root);
	while(!queue.empty()) {
		BinaryTreeNode* cur=queue.front();
		cout<<" "<<cur->m_key;//visit
		queue.pop();
		if(cur->m_pLeft!=NULL) queue.push(cur->m_pLeft);
		if(cur->m_pRight!=NULL) queue.push(cur->m_pRight);
	}
}    
#include  <iostream>
#include <stack>
#include <queue>  
using namespace std;

// 二叉树节点结构体
struct BinaryTreeNode {
	int m_key;
	BinaryTreeNode* m_pLeft;
	BinaryTreeNode* m_pRight;
};

/****************************************
func:根据前序序列和中序序列构建二叉树
para:preOrder:前序序列;midOrder:中序序列;len:节点数
****************************************/
BinaryTreeNode* construct(int* preOrder,int* midOrder,int len) {
	if(preOrder==NULL||midOrder==NULL||len<=0) return NULL;

	//先序遍历的第一个值是根结点的键值
	int rootKey=preOrder[0];
	BinaryTreeNode* root=new BinaryTreeNode;
	root->m_key=rootKey;
	root->m_pLeft=root->m_pRight=NULL;
	
	//只有一个节点
	if(len==1 && *preOrder == *midOrder) return root;
	
	//在中序遍历中找到根节点的值
	int* rootMidOrder=midOrder;
	int leftLen=0; //左子树节点数
	while(*rootMidOrder!=rootKey&&rootMidOrder<=(midOrder+len-1)) {
		++rootMidOrder;
		++leftLen;
	}
	//在中序序列未找到根结点,输入错误
	if(*rootMidOrder!=rootKey) return NULL;
	
	//构建左子树
	if(leftLen>0) {
		root->m_pLeft=construct(preOrder+1,midOrder,leftLen);
	}
	//构建右子树
	if(len-leftLen-1>0) {
		root->m_pRight=construct(preOrder+leftLen+1,rootMidOrder+1,len-leftLen-1);
	}
	return root;
}

int main() {
	// 先序序列
	int preOrder[8]={1,2,4,7,3,5,6,8};
	// 中序序列
	int midOrder[8]={4,7,2,1,5,3,8,6};
    // 建树
	BinaryTreeNode* root=construct(preOrder, midOrder, 8);
	
	cout<<"---preOrder---"<<endl;
	cout<<"recursion version: ";
	preOrderRecursion(root);
	cout<<endl<<"stack version: ";
	preOrderStack(root);
	
	cout<<endl<<endl<<"---midOrder---"<<endl;
	cout<<"recursion version: ";
	midOrderRecursion(root);
	cout<<endl<<"stack version1: ";
	postOrderStack1(root);
	cout<<endl<<"stack version2: ";
	postOrderStack2(root);
	
	cout<<endl<<endl<<"---postOrder---"<<endl;
	cout<<"recursion version: ";
	postOrderRecursion(root);
	cout<<endl<<"stack version: ";
	postOrderStack1(root);
	
	cout<<endl<<endl<<"---Breadth First Order---"<<endl;
	breadthFirstOrder(root);
}

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值