在排序中,之前利用大小根堆的方式,保持最小值或者最大值在堆顶端
二叉排序树是保持这棵树一直是有序的
二叉排序树的建立,不同于堆操作只需要对非叶子节点进行处理,保持其大于左右孩子,或者是小于左右孩子,而是需要对每一个点都进行处理,因为他是相对而言更加
严谨的操作
查找一个数据:对于大根堆操作,如果当前值小于根节点,那么这个值在左右分支出现都是由可能得,但是对于BST,如果小那么肯定在左分支,如果大,那么肯定在右分支
删除一个元素:对于堆,一般都是由于排序会删除堆顶元素,那么删除之后由最后一个元素补上,然后再检验其情况
对于二叉树,如果删除的元素只有一个孩子,那么由这个孩子代替,如果有两个孩子,那么在右分支中找到最小的元素代替
#include <iostream> #include <stack> using namespace std; //二叉排序树,完成创建节点,插入节点,删除节点,查找节点,中序遍历的功能 //节点类定义 class Node{ public: int data;//数据 Node *parent;//父节点 Node *left;//左子节点 Node *right;//右子节点 public: Node():data(-1),parent(NULL),left(NULL),right(NULL){} Node(int num):data(num),parent(NULL),left(NULL),right(NULL){} }; //二叉排序树类定义 class Tree{ public: Tree(int num[],int len);//插入num数组的前len个数据 void InsertNode1(int data);//插入节点,非递归方法 void InsertNode(int data);//插入节点,递归方法 Node* SearchNode(int data);//查找节点,递归方法 void DeleteNode(int data);//删除节点及其子树,递归方法 void InOrderTree();//中序遍历,递归方法 void InOrderTreeUnRec(); private: void InsertNode(Node *current,int data);//递归插入方法 Node *SearchNode(Node *current,int data);//递归查找方法 void DeleteNode(Node *current);//递归删除方法 void InOrderTree(Node *root);//中序遍历,递归方法 private: Node *root;//二叉排序树的根节点 }; //构造函数中创建二叉排序树 //首先生成根节点,然后循环调用插入节点函数使二叉排序树进行插入操作 Tree::Tree(int num[], int len){ root=new Node(num[0]);//建立root节点 //把数组中的其他数据插入到二叉排序树中 for (int i=1;i<len;i++){ //InsertNode(num[i]); InsertNode1(num[i]); } } //插入节点操作 //插入数据为参数data的节点,非递归方法 void Tree::InsertNode1(int data){ Node *p,*par; Node *newNode=new Node(data);//创建节点 p=par=root; while (p!=NULL){//查找插入在哪个节点下面 par=p;//保存节点 if (data>p->data){ //如果data大于当前节点的data p=p->right;//下一步到右子节点 } else if (data<p->data){//如果data小于当前节点的data p=p->left;//下一步到左子节点 } else if (data==p->data){//不能插入重复数据 delete newNode; return; } } newNode->parent=par; if (par->data>newNode->data){ //把新节点插入在目标节点的正确位置 par->left=newNode; } else par->right=newNode; } //插入节点操作 //插入数据为参数data的节点,递归方法,内部调用了private成员函数InsertNode() void Tree::InsertNode(int data){ if (root!=NULL){ InsertNode(root,data);//调用递归插入方法 } } //递归插入方法 void Tree::InsertNode(Node *current, int data){ if (data<current->data){//如果data小于当前节点数据,在当前节点的左子树插入 if (current->left==NULL){//如果左子节点不存在,则插入到左节点 current->left=new Node(data); current->left->parent=current; } else InsertNode(current->left,data);//对左节点进行递归调用 } else if (data>current->data){//如果data大于当前节点数据,则当前节点的右边子树插入 if (current->right==NULL){//如果右子树不存在,则插入到右节点 current->right=new Node(data); current->right->parent=current; } else InsertNode(current->right,data);//对右节点进行递归调用 } return; //data等于当前节点数据时,不插入 } //递归查找方法 Node* Tree::SearchNode(Node *current, int data){ if (data<current->data){//如果data小于当前节点数据,递归搜索其左子树 if (current->left==NULL){//如果不存在左子树,返回NULL return NULL; } return SearchNode(current->left,data); } else if (data>current->data){//如果data大于当前节点数据,递归搜索其右子树 if (current->right==NULL){//如果不存在右子树,返回NULL return NULL; } return SearchNode(current->right,data); } return current;//如果相等返回current } //查找节点 Node* Tree::SearchNode(int data){ if (root==NULL){ return NULL; } return SearchNode(root,data); } //删除数据为data的节点及其子树 void Tree::DeleteNode(int data){ Node *current=NULL; current=SearchNode(data);//查找节点 if (current!=NULL){ DeleteNode(current);//删除节点及其子树 } } //删除current节点及其子树的所有节点 void Tree::DeleteNode(Node *current){ if (current->left!=NULL){ //删左子树 DeleteNode(current->left); } if (current->right!=NULL){//删右子树 DeleteNode(current->right); } if (current->parent==NULL){//如果current是根节点,把root置空 delete current; root=NULL; return; } //将current父亲节点的相应指针置空 if (current->parent->data>current->data){ //current为其父节点的左子节点 current->parent->left=NULL; } else{//current为其父节点的右子节点 current->parent->right=NULL; } //最后删除此节点 delete current; } //中序遍历,递归方法 void Tree::InOrderTree(Node *current){ if (current!=NULL){ InOrderTree(current->left);//遍历左子树 cout<<current->data<<" ";//打印节点数据 InOrderTree(current->right);//遍历右子树 } } //中序遍历 void Tree::InOrderTree(){ if (root==NULL){ cout<<"The Tree Is Empty!"<<endl; getchar(); return; } InOrderTree(root); } //中序遍历,非递归方法 /*可以用栈来临时存储节点 先将根节点存入栈中,遍历左子树 遍历完左子树返回时,栈顶元素应为根节点,此时出栈,并打印节点数据 在中序遍历右子树 */ void Tree::InOrderTreeUnRec(){ stack<Node *>s; Node *p=root; while (p!=NULL ||!s.empty()){ while (p!=NULL){//遍历左子树 s.push(p);//把遍历的节点全部压栈 p=p->left; } if (!s.empty()){ p=s.top();//得到栈顶内容 s.pop();//出栈 cout<<p->data<<" ";//打印 p=p->right;//指向右子节点,下一次循环时就会中序遍历右子树 } } } int main() { /* 测试程序*/ int num[5]={1,2,6,4}; Tree t(num,4); Node *p=NULL; t.InOrderTree(); cout<<endl; t.InOrderTreeUnRec(); cout<<endl; //t.InsertNode1(7); t.InsertNode(0); t.InOrderTree(); cout<<endl; t.InOrderTreeUnRec(); cout<<endl; p=t.SearchNode(4); if (p!=NULL){ cout<<p->data<<endl; } else cout<<"Not Find!"<<endl; t.DeleteNode(2); t.InOrderTree(); cout<<endl; t.InOrderTreeUnRec(); system("pause"); return 0; }
时间: 2024-10-16 15:35:23