数据结构和算法——二叉排序(查找)树及实现

1. 优先队列  大根堆  小根堆,先比较谁的优先级高  
2.树,一般用递归来实现,也可以用循环和栈来实现。

  可空;
  如果非空,由根节点和若干个互不交叉的分支组成,每个分支也是树,称为子树

3.二叉树:
  如果每个节点最多只有两个分支,就称为二叉树
  每个节点都是两个分支的话就称为满二叉树;
  相反是完全二叉树。

  二叉树的节点包括一个数据,两个指向左右两个子节点的指针

处理树的基本思路


  二叉查找树
  约定:左小于根,右大于根或不小于根

  要插入的数比根节点小,所以只在左分支找,比根节点大就在右边找


删除一个结点

1 找到要删除的结点的指针t

2 将指针另存一份p

3 左右结点合并(左结点放到右结点的左下方)用insert函数可自动完成

4 将Pn指向合并后的子树

5 delete p

6 结点数n--


01tree.cpp

<span style="font-size:18px;">#include <iostream>
using namespace std;
#include <iomanip>
typedef char T;
class bst{
	struct Node{
		T data;
		Node* L;
		Node* R;
		Node(const T& d):data(d),L(),R(){}
		Node(const T& d,Node*l,Node*r):data(d),L(l),R(r){}
	};
	typedef Node* tree;
	Node* rp;
	int n;
public:
	bst():rp(),n(){}
	void clear(){clear(rp);n=0;}
	~bst(){clear();}
	void insert(const T& d){insert(rp,new Node(d));++n;}
	tree& find(const T& d){return find(rp,d);}
	void travel()const{travel(rp);cout<<endl;}
	bool empty()const{return rp==NULL;}
	bool remove(const T& d){删除节点
		tree& t = find(d);
		if(t==NULL) return false;
		Node* p = t;
		if(t->L!=NULL) insert(t->R, t->L);
		t = t->R;
		delete p;
		--n;
		return true;
	}
	const T& root()const{if(!rp) throw"空";return rp->data;}
	int size()const{return n;}
	void update(const T& olddata,const T& newdata){
		if(remove(olddata)) insert(newdata);
	}
	void insert(tree& t, Node* p){//添加结点
		if(t==NULL) t = p;
		else if(p->data < t->data) insert(t->L,p);
		else insert(t->R,p);
	}
	tree& find(tree& t, const T& d){//返回以d为根的子树的根指针
		if(t==NULL) return t;//没找到
		else if(d==t->data) return t;//找到了
		else if(d<t->data)	return find(t->L,d);
		else return find(t->R,d);
	}
	void travel(tree t)const{//遍历
		if(t!=NULL){
			travel(t->L);
			cout << t->data << ' ';
			travel(t->R);
		}
	}
	void clear(tree& t){
		if(t!=NULL){
			clear(t->L);
			clear(t->R);
			delete t; t=NULL;
		}
	}
	int high(tree t){
		if(t==NULL) return 0;
		int lh = high(t->L);
		int rh = high(t->R);
		return 1+(lh>rh?lh:rh);
	}</span><span style="font-size:18px;">
        //树状打印 中间根结点 上边右结点 下面左结点</span><span style="font-size:18px;">
	void print(tree t, int space, char sign){
		if(t==NULL) return;
		print(t->R,space+3,'/');
		cout << setw(space+1) << sign << t->data << endl;
		print(t->L,space+3,'\\');
	}
	void print(){ print(rp,0,'*');cout<<"---------"<<endl; }
};
int main()
{
	bst b;
	b.insert('k');b.insert('s');b.insert('f');b.insert('t');
	b.insert('a');b.insert('m');b.insert('x');b.insert('e');
	b.insert('w');b.insert('b');b.insert('u');b.insert('j');
	b.print();
	b.remove('k');b.remove('m');b.remove('j');b.remove('u');
	b.print();
	b.update('b','k');b.update('k','b');b.update('x','*');
	b.print();
	while(!b.empty()) b.remove(b.root());
	cout<<"size:"<<b.size()<<endl;
	b.print();
}
</span>


描述 用函数实现如下二叉排序算法: (1) 插入新结点 (2) 前序、中序、后序遍历二叉 (3) 中序遍历的非递归算法 (4) 层次遍历二叉 (5) 在二叉查找给定关键字(函数返回值为成功1,失败0) (6) 交换各结点的左右子 (7) 求二叉的深度 (8) 叶子结点数 Input 第一行:准备建的结点个数n 第二行:输入n个整数,用空格分隔 第三行:输入待查找的关键字 第四行:输入待查找的关键字 第五行:输入待插入的关键字 Output 第一行:二叉的先序遍历序列 第二行:二叉的中序遍历序列 第三行:二叉的后序遍历序列 第四行:查找结果 第五行:查找结果 第六行~第八行:插入新结点后的二叉的先、中、序遍历序列 第九行:插入新结点后的二叉的中序遍历序列(非递归算法) 第十行:插入新结点后的二叉的层次遍历序列 第十一行~第十三行:第一次交换各结点的左右子后的先、中、后序遍历序列 第十四行~第十六行:第二次交换各结点的左右子后的先、中、后序遍历序列 第十七行:二叉的深度 第十八行:叶子结点数 Sample Input 7 40 20 60 18 50 56 90 18 35 30 Sample Output 40 20 18 60 50 56 90 18 20 40 50 56 60 90 18 20 56 50 90 60 40 1 0 40 20 18 30 60 50 56 90 18 20 30 40 50 56 60 90 18 30 20 56 50 90 60 40 18 20 30 40 50 56 60 90 40 20 60 18 30 50 90 56 40 60 90 50 56 20 30 18 90 60 56 50 40 30 20 18 90 56 50 60 30 18 20 40 40 20 18 30 60 50 56 90 18 20 30 40 50 56 60 90 18 30 20 56 50 90 60 40 4 4
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值