一、二叉树的递归遍历
void PreOrderTraversal(BinTree BT) {
if (BT) {
printf("%d", BT->Data);
PreOrderTraversal(BT->Left);
PreOrderTraversal(BT->Right);
}
}
void InOrderTraversal(BinTree BT) {
if (BT) {
InOrderTraversal(BT->Left);
printf("%d", BT->Data);
InOrderTraversal(BT->Right);
}
}
void PostOrderTraversal(BinTree BT) {
if (BT) {
PostOrderTraversal(BT->Left);
PostOrderTraversal(BT->Right);
printf("%d", BT->Data);
}
}
二、二叉搜索树的查找操作
迭代实现:
Position IterFind(int X, BinTree BST) {
while (BST) {
if (X > BST->Data) {
BST = BST->Right;
}
else if (X < BST->Data) {
BST = BST->Left;
}
else {
return BST;
}
}
return NULL;//查找失败
}
递归实现:
Position Find(int X, BinTree BST) {
if (!BST) {
return NULL;
}
if (X > BST->Data) {
return Find(X, BST->Right);
}
else if (X < BST->Data) {
return Find(X, BST->Left);
}
else {
return BST;
}
}
插入操作:
BinTree Insert(Element Type X,BinTree BST){
if(!BST){
//若原树为空,生成并返回一个结点的二叉搜索树
BST=malloc(sizeof(struct TreeNode));
BST->Data=X;
BST->Left=BST->Right=NULL;
}else{//开始找要插入元素的位置
if(X<BST->Data)
BST->Left=Insert(X,BST->Left);
//递归插入左子树
}else if(X>BST->Data)
BST->Right=Insert(X,BST->Right);
//else X已经存在,什么也不做
return BST;
}
删除操作:
1、要删除的是叶结点,直接删除,并再修改其父结点指针,置为NULL
2、要删除的结点只有一个孩子结点:将其父结点的指针指向要删除结点的孩子结点
3、要删除的结点有左、右两棵子树:
用另一结点替代被删除结点:右子树的最小元素或者左子树的最大元素
BinTree Delete(int X,BinTree BST){
Position Tmp;
if(!BST)printf("要删除的元素未找到");
else if(X<BST->Data)
BST->Left=Delete(X,BST->Left);//左子树递归删除,将新的左子树根结点的地址赋给Left
else if(X>BST->Data)
BST->Right=Delete(X,BST->Right);//右子树递归删除
else{//找到要删除的结点
if(BST->Left&&BST->Right){//被删除的结点有左右两个子结点
Tmp=FindMin(BST->Right);//在右子树中找最小的元素填充删除结点
BST->Data=Tmp->Data;
BST->Right=Delete(BST->Data,BST->Right);
//在删除结点的右子树中删除最小元素
}else{//这种情况为被删除结点有一个或无子结点
Tmp=BST;
if(!BST->Left)//有右孩子或无子结点
BST=BST->Right;
else if(!BST->Right)
BST=BST->Left;
free(Tmp);
}
}
return BST;
}
三、STL中的平衡二叉树数据结构
为什么要使用平衡二叉树,而不使用普通的容器排序+二分查找呢?因为有时需要在大量增加、删除数据的同时,还要进行大量数据的查找
希望增加数据、删除数据、查找数据都能在log(n)复杂度内完成
所以可以使用”平衡二叉树“数据结构存放数据,在STL中,就是以下四种”排序容器“:
multiset set multimap map
multiset用法
multiset<T> st;
定义了一个multiset变量st,st里面存放T类型的数据,并且自动排序,开始St为空
排序规则:若a<b 为true,则a排在b前面
st.insert添加元素,st.find查找元素,st.erase删除元素
复杂度都是log(n)
multiset上的迭代器:
multiset<T>::iterator p;
p是迭代器,相当于指针,可用于指向multiset中的元素,访问multiset中的元素要通过迭代器
st.begin(),返回值类型是multiset<T>::iterator,是指向st头一个元素的迭代器
St.end(),返回值类型为multiset<T>::iterator,是指向st中最后一个元素后面的迭代器
对迭代器++,其指向容器中下一个元素,--则令其指向上一个元素
实例:
#include<iostream>
#include<cstring>
#include<set>
using namespace std;
int main(){
multiset<int> st;
int a[10]={1,14,12,13,7,13,21,19,8,81};
for(int i=0;i<10;i++){
st.insert(a[i]);
}
multiset<int>::iterator i;//i是迭代器,相当于指针
for(i=st.begin();i!=st.end();i++){
cout<<*i<<",";
}
cout<<endl;
}
其他用法:
i=st.find(22)//查找22,返回值是迭代器类型,如果找不到,则返回st.end()
if(i==st.end()){
cout<<"Not found"<<endl;
}
st.insert(22);
i=st.find(22);
if(i==st.end()){
cout<<"Not found"<<endl;
}else{
cout<<"found:"<<*i<<endl;
}
i=st.lower_bound(13)
//返回最靠后的迭代器it,使得[begin(),it)中的元素都在13前面
cout<<*i<<endl;
i=st.upper_bound(8);
//返回最靠前的迭代器it,使得[it,end())中的元素都在8后面
cout<<*i<<endl;
st.erase(i);//删除迭代器i指向的元素
for(i=st.begin();i!=st.end();i++){
cout<<*i<<",";
}
return 0;