二叉排序树,完成创建节点,插入节点,删除节点,查找节点,中序遍历的功能

 
#include "stdafx.h"
#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 _tmain(int argc, _TCHAR* argv[])
{
	/* 测试程序*/
	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;
}


 

  • 0
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值