bst总结

来源:互联网 发布:mysql 事务实现原理 编辑:程序博客网 时间:2024/05/24 04:49
#include <iostream>
#include <stack>
#include <queue>
//using stack;
using namespace std;


struct Node
{
int data;
Node *left;
Node *right;
};






Node* insert(Node*p, int n)
{
Node *f = p;
Node *r = p;
while (p != NULL)
{
f = p;
if (n < p->data)
p = p->left;
else if (n > p->data)
p = p->right;
else
return p;
}
p = new Node;
p->data = n;
p->left = NULL;
p->right = NULL;
if (f)
{
if (n < f->data)
f->left = p;
else
f->right = p;
return r;
}


return p;


}


Node* creat(Node *p, int *pi, int m, int n)
{
if(m > n)
return p;
int x = m+((n-m)>>1);
p = new Node;
p->data = pi[x];
p->left = NULL;
p->right = NULL;


p->left = creat(p->left, pi, m, x-1);
p->right = creat(p->right, pi, x+1, n);
return p;
}


void del(Node *p)
{
if (p==NULL)
return;
if (p->left != NULL)
del(p->left);
if (p->right != NULL)
del(p->right);
delete p;
p = NULL;
}


void preOrder0(Node *p)
{
if(p == NULL)
return;
cout<<p->data<<" ";
preOrder0(p->left);
preOrder0(p->right);
}


void inOrder0(Node *p)
{
if(p == NULL)
return;
inOrder0(p->left);
cout<<p->data<<" ";
inOrder0(p->right);
}


void postOrder0(Node *p)
{
if(p == NULL)
return;
postOrder0(p->left);
postOrder0(p->right);
cout<<p->data<<" ";
}
//迭代,前序遍历
void preOrder(Node *p)
{
if (p == NULL)
return;
stack<Node*>st;
while(true)
{
for(;p != NULL; p = p->left)
{
cout<<p->data<<" ";
if (p->right != NULL)
st.push(p->right);
}


if (!st.empty())
{
p = st.top();
st.pop();
}else
{
break;
}


}

}
// 迭代,中序遍历
void inOrder(Node *p)
{
if (p == NULL)
return;
stack<Node*>st;
while(true)
{
for(;p != NULL; p = p->left)
{
st.push(p);
}


if (!st.empty())
{
p = st.top();
st.pop();
cout<<p->data<<" ";
p = p->right;
}else
{
break;
}


}

}
// 迭代,后序遍历
void postOrder(Node *p)
{
if (p == NULL)
return;
stack<Node*>st;
Node *last = NULL;
while(true)
{
for(; p!=NULL; p=p->left)
st.push(p);

while(true)
{
if (st.empty())
return;
p = st.top();

if (p->right != NULL && p->right != last)
{
p = p->right;
break;
}
else
{
cout<<p->data<<" ";
last = p;
st.pop();
}
}
}//
}
//层次遍历
void cengci(Node *p)
{
if (p == NULL)
return;
queue<Node*>q;
q.push(p);
while(!q.empty() )
{
Node *tmp = q.front();
q.pop();
cout<<tmp->data<< " ";
if (tmp->left != NULL)
q.push(tmp->left);
if (tmp->right != NULL)
q.push(tmp->right);
}
}


//节点个数
void numNode(Node *p, int &a)
{
if(p == NULL)
return;
++a;
//cout<<p->data<<" ";
numNode(p->left, a);
numNode(p->right, a);
}
//叶子节点个数
void numLeafNode(Node *p, int &a)
{
if(p == NULL)
return;
if (p->left ==NULL && p->right == NULL)
++a;
//cout<<p->data<<" ";
numLeafNode(p->left, a);
numLeafNode(p->right, a);
}
// 求深度
void depth(Node *p, int &d)
{
if(p==NULL)
{
d = 0;
return;
}
int d1 = 0, d2 = 0;
depth(p->left, d1);
depth(p->right, d2);
d1 = d1 > d2 ? d1 : d2;
d = d + 1 + d1;
}


static void turn2list(Node *p, Node *&head, Node *&tail)
{
if(p->left != NULL)
turn2list(p->left, head, tail);


p->left = tail;
if (tail == NULL)
{
head = p;
}else
{
tail->right = p;
}
tail = p;


if(p->right != NULL)
turn2list(p->right, head, tail);
}
// 变成有序双向链表
void bst2Link(Node *p, Node *&lin)
{
if(p==NULL)
{
lin = p;
return;
}


Node *head = NULL, *tail = NULL;
turn2list(p,head,tail);
lin = head;
}


static void visitList(Node *head)
{
cout<<"正向list:"<<endl;
Node *p=head;
while(head)
{
p=head;
cout<<head->data<<" ";
head = head->right;



cout<<endl<<"反向list:"<<endl;
while(p)
{

cout<<p->data<<" ";
p = p->left;

}


static void numofk(Node *p, int &ceng, int &num, int k)
{
if(p==NULL)
return;
++ceng;
if (ceng == k)
++num;
numofk(p->left, ceng, num, k);
numofk(p->right, ceng, num, k);
--ceng;
}


// 第k层的节点个数
int numK(Node *p, int k)
{
if(p==NULL)
return 0;
int ceng = 0;
int num = 0;
numofk(p, ceng, num, k);
return num;
}


static bool isping(Node *p, int &n)
{
if(p == NULL)
{
n = 0;
return true;
}
int n1 = 0;
int n2 = 0;
bool is = true;
is = is && isping(p->left, n1);
is = is && isping(p->right, n2);

n = ((n1>n2)?n1:n2) + 1;
if(!is || n1 - n2 > 1 || n2 - n1 > 1)
return false;
return true;
}
// 是否为平衡二叉树
bool isPingHeng(Node *p)
{
int n = 0;
return isping(p, n);
}
// 是否为完全二叉树
bool iswanquan(Node *p)
{
if (p == NULL)
return true;
queue<Node*>q;
q.push(p);
bool flag = false;
while(!q.empty() )
{
Node *tmp = q.front();
q.pop();
//cout<<tmp->data<< " ";
if (tmp->left != NULL)
{
if(flag)
return false;
q.push(tmp->left);
}
else if(!flag)
{
flag = true; 
}


if (tmp->right != NULL)
{
if(flag)
return false;
q.push(tmp->right);
}

}
return true;
}


// 由前序遍历和中序遍历重建二叉树.a[m1]-a[n1]是前序遍历,b[m2]-b[n2]是中序遍历
Node *chongjian(int *a, int m1, int n1, int *b, int m2, int n2)
{
if(m1>n1 || m2>n2 || n1-m1!=n2-m2)
return NULL;

int i;
int h = a[m1];
for(i=m2; i<=n2; i++)
{
if(h == b[i])
break;
}
if(i>n2)return NULL;   //正常情况下不会发生


Node *p = new Node;
int x = m1+i-m2;
p->data = h;
p->left  = chongjian(a, m1+1, x, b, m2, i-1);
p->right = chongjian(a, x+1, n1, b, i+1, n2);
return p;
}


// 两个节点的最大距离
// max(左子树最大距离,右子树最大距离,左子树深度+右子树深度+1)
// 需要用到求深度的函数
int getdist(Node *p )
{
if(p==NULL)
return 0;
int h1 = 0;
depth(p->left, h1); // 左子树深度
int h2 = 0;
depth(p->right, h2); //右子树深度
int h = h1 + h2 + 1;     // 
h1 = getdist(p->left);  // 左子树最大距离
h2 = getdist(p->right); //右子树最大距离
h = h>h1?h:h1;
h = h>h2?h:h2;


return h;


}
// 普通二叉树查找(其实就是先序遍历)
Node *find(Node *p, int x)
{
if (p==NULL)
return NULL;
if (p->data == x)
return p;
Node * tmp = find(p->left, x);
if(tmp!=NULL)
return tmp;
return find(p->right, x);
}


// 找到根节点到值为x节点的路径
static bool find_path(Node *p, int x, vector<Node*>&path)
{
if(p==NULL)
return false;
path.push_back(p);
if(p->data == x)
return true;
bool is1=false, is2=false;

// 左
//path.push_back(p->left);
is1 = find_path(p->left, x, path);
if(is1)
return true;
//path.pop_back();


// 右
//path.push_back(p->right);
is2 = find_path(p->right, x, path);
if(is2)
return true;
//path.pop_back();
path.pop_back();
return false;


}


// 两个节点的公共祖先
Node *commonF(Node *p, int x, int y)
{
vector<Node*>v1;
vector<Node*>v2;
bool is1 = find_path(p, x, v1);
bool is2 = find_path(p, y, v2);
if (!is1 || !is2)
return NULL;


int n = v1.size() < v2.size() ? v1.size() : v2.size();
int i;
for (i=0; i<n; i++)
{
//cout<<"  "<<v1[i]->data<<" "<<v2[i]->data<<endl;
if(v1[i]!=v2[i])
break;
}


return v1[i-1];


}


int main()
{


Node * p=NULL;


p = insert(p,6);
p = insert(p,3);
p = insert(p,8);
p = insert(p,2);
p = insert(p,1);
p = insert(p,4);
//p = insert(p,5);
p = insert(p,9);
p = insert(p,7);


cout<<"前序遍历"<<endl;
cout<<"迭代: ";
preOrder(p);
cout<<endl;
cout<<"递归: ";
preOrder0(p);
cout<<endl;


cout<<"中序遍历"<<endl;
cout<<"迭代: ";
inOrder(p);
cout<<endl;
cout<<"递归: ";
inOrder0(p);
cout<<endl;


cout<<"后序遍历"<<endl;
cout<<"迭代: ";
postOrder(p);
cout<<endl;
cout<<"递归: ";
postOrder0(p);
cout<<endl;

cout<<"层次遍历:"<<endl;
cengci(p);
cout<<endl;


int a;


a = 0;
numNode(p,a);
cout<<"  节点个数: "<<a<<endl;


a = 0;
numLeafNode(p,a);
cout<<"叶子节点个数: "<<a<<endl;


a = 0;
depth(p,a);
cout<<"高度: "<<a<<endl;


int i;
for(i=1; i<=a; i++)
{
cout<<"第"<<i<<"层的节点数: "<<numK(p,i)<<endl;
}

// Pingheng
bool is = isPingHeng(p);
if (is)
cout<<"是平衡二叉树"<<endl;
else
cout<<"不是平衡二叉树"<<endl;


bool isWan = iswanquan(p);
if (isWan)
cout<<"是完全二叉树"<<endl;
else
cout<<"不是完全二叉树"<<endl;




int qian[] ={6,3,2,1,4,5,8,7,9};
int zhong[]={1,2,3,4,5,6,7,8,9};
Node *xin = chongjian(qian,0,8,zhong,0,8);
cout<<endl<<"中序遍历"<<endl;
inOrder(xin);
cout<<endl<<"层次遍历:"<<endl;
cengci(xin);
cout<<endl;


cout<<"p的节点最大距离: "<<getdist(p)<<endl;




vector<Node*>vn;
int x = 7;
bool isf = find_path(p, x, vn);
int j;
cout<<"根节点到 " <<x<<" 的路径:"<<endl;
for(j=0; j<vn.size(); ++j)
cout<<vn[j]->data<<" --> ";
cout<<endl;




// 寻找1和4的最近公共祖先
Node * fn = commonF(p, 1, 4);
cout<<"1和4的最近公共祖先: "<<fn->data<<endl;


// 变为链表
Node *head = NULL;
bst2Link(p, head);
visitList(head);


del(p);
return 0;
}