二叉树首先要有树节点

template<class T>
class BinaryNode
{
public:
T element;
BinaryNode *left;
BinaryNode *right; public:
BinaryNode(T passelement);
~BinaryNode();
}; template<class T>
BinaryNode<T>::BinaryNode(T passelement)
{
this->element=passelement;
this->left=NULL;
this->right=NULL;
} template<class T>
BinaryNode<T>::~BinaryNode()
{
}

二叉树对象则比较复杂

 template<class T>
class BinarySearchTree
{
private:
BinaryNode<T> *m_proot;
public:
const T findMin() const;//获取最小值
const T findMax() const;//获取最大值
bool contains(const T& xele) const;//判断是否包含
void makeEmpty();//清空二叉树
void insert(const T& xele);//插入
void remove(const T& xele);//删除
void inordertrav();//中序遍历
void toDoublelist();//转化为双向链表
void printDoublelist();//打印双向链表
public://构造与析构函数
BinarySearchTree();
BinarySearchTree(const BinarySearchTree& bst);
~BinarySearchTree();
private://全部用于递归调用
void makeEmpty(BinaryNode<T>* &t);
const T findMin(BinaryNode<T>* &t);
void remove(const T& xele, BinaryNode<T>* &t);
void insert(const T& xele, BinaryNode<T>* &t);
void inordertrav(BinaryNode<T>* &t);
void toDoublelist(BinaryNode<T>* &t);
BinaryNode<T>* getlLeftTail(BinaryNode<T>* &t);//获取左子树的最大节点
BinaryNode<T>* getlRightHead(BinaryNode<T>* &t);//获取右子树的最小节点
};

具体函数实现如下:

1.判断是否包含:

template<class T>
bool BinarySearchTree<T>::contains(const T& xele) const
{
BinaryNode<T>* pcurrent = m_proot;
while (true)
{
if (pcurrent == NULL)//指针为空
{
return false;
}
else if (xele < pcurrent->element)
pcurrent = pcurrent->left;
else if (xele > pcurrent->element)
pcurrent = pcurrent->right;
else
{
pcurrent = NULL;
return true;
}
} }

2.返回最小值:

template<class T>
const T BinarySearchTree<T>::findMin() const
{
BinaryNode<T>* m_pcurrent = m_proot;
while (m_pcurrent->left != NULL)
{
m_pcurrent = m_pcurrent->left;
}
return m_pcurrent->element;
}

或:

template<class T>
const T BinarySearchTree<T>::findMin(BinaryNode<T>* &t)
{
if (t == NULL)
return NULL;
if (t->left == NULL)
return t->element;
else
return findMin(t->left); }
template<class T>
const T BinarySearchTree<T>::findMin()
{
findMin(m_proot);
}

3.返回最大值:

template<class T>
const T BinarySearchTree<T>::findMax() const
{
BinaryNode<T>* m_pcurrent = m_proot;
while (m_pcurrent->right != NULL)
{
m_pcurrent = m_pcurrent->right;
}
return m_pcurrent->element;
}

4.清空:

template<class T>
void BinarySearchTree<T>::makeEmpty(BinaryNode<T>* &t)
{
if (t!=NULL)
{
makeEmpty(t->left);
makeEmpty(t->right);
delete t;
}
t = NULL;
}
template<class T>
void BinarySearchTree<T>::makeEmpty()
{
makeEmpty(m_proot);
}

5.插入:

template<class T>
void BinarySearchTree<T>::insert(const T& xele, BinaryNode<T>* &t)
{
if (t == NULL)
t = new BinaryNode<T>(xele);
else if (xele < t->element)
return insert(xele, t->left);
else if (xele > t->element)
return insert(xele, t->right);
else
;
}
template<class T>
void BinarySearchTree<T>::insert(const T& xele)
{
insert(xele, m_proot);
}

6.删除:

template<class T>
void BinarySearchTree<T>::remove(const T& xele, BinaryNode<T>* &t)
{
if (t == NULL)
return;
else if (xele < t->element)
remove(xele, t->left);
else if (xele > t->element)
remove(xele, t->right);
else
{
if (t->left != NULL&&t->right != NULL)
{
t->element = findMin(t->right);
remove(t->element, t->right);
}
else
{
BinaryNode<T>* oldNode = t;
t = (t->left != NULL) ? t->left : t->right;
delete oldNode;
}
}
}
template<class T>
void BinarySearchTree<T>::remove(const T& xele)
{
remove(xele, m_proot);
}

7.中序遍历:

template<class T>
void BinarySearchTree<T>::inordertrav()
{
inordertrav(m_proot);
}
template<class T>
void BinarySearchTree<T>::inordertrav(BinaryNode<T>* &t)//参数是根节点
{
if (NULL == t)
return;
if (NULL != t->left)
inordertrav(t->left);
cout << t->element << "," << endl;
if (NULL != t->right)
inordertrav(t->right);
}

8.转换为双向链表,需要注意的是:不能使用中序遍历的方法去实现转换,这样会引起指针异常;转换后以前操作二叉树的函数全部失效

template<class T>
BinaryNode<T>* BinarySearchTree<T>::getlLeftTail(BinaryNode<T>* &t)
{
BinaryNode<T>* pC = t;
while (true)
if (NULL != pC->right)
pC = pC->right;
else
break;
return pC;
}
template<class T>
BinaryNode<T>* BinarySearchTree<T>::getlRightHead(BinaryNode<T>* &t)
{
BinaryNode<T>* pC = t;
while (true)
if (NULL != pC->left)
pC = pC->left;
else
break;
return pC;
}
template<class T>
void BinarySearchTree<T>::toDoublelist()
{
toDoublelist(m_proot);
}
template<class T>
void BinarySearchTree<T>::toDoublelist(BinaryNode<T>* &t)
{ if (NULL == t)
return;
if (NULL != t->left)
{
BinaryNode<T>* listtail = getlLeftTail(t->left);//先记录下来要与根节点的左指针相连的。
toDoublelist(t->left);
listtail->right = t;
t->left = listtail;
} /*这个方法会出现问题
//不为空
if (NULL != m_plist)
{
t->left = m_plist;
m_plist->right = t;
}
else//为空表示使双向链表的头
{
m_phead = t;
}
//为下一次连接做准备
m_plist = t; cout << m_plist->element << ",";*/ if (NULL != t->right)
{
BinaryNode<T>* listhead = getlRightHead(t->right);
toDoublelist(t->right);
listhead->left = t;
t->right = listhead; } }

9.打印链表:

template<class T>
void BinarySearchTree<T>::printDoublelist()
{
BinaryNode<T>* phead = m_proot;
while (true)
{
if (phead->left != NULL)
phead = phead->left;
else
break;
}
while (phead->right!=NULL)
{
cout << phead->element << ",";
phead = phead->right;
}
cout << phead->element;
}

C++二叉查找树实现及转化为双向链表的更多相关文章

  1. 【剑指offer】二叉搜索树转双向链表

    转载请注明出处:http://blog.csdn.net/ns_code/article/details/26623795 题目描写叙述: 输入一棵二叉搜索树,将该二叉搜索树转换成一个排序的双向链表. ...

  2. [LeetCode] Convert Binary Search Tree to Sorted Doubly Linked List 将二叉搜索树转为有序双向链表

    Convert a BST to a sorted circular doubly-linked list in-place. Think of the left and right pointers ...

  3. 剑指offer26:将二叉搜索树转换成一个排序的双向链表。要求不能创建任何新的结点,只能调整树中结点指针的指向。

    1 题目描述 输入一棵二叉搜索树,将该二叉搜索树转换成一个排序的双向链表.要求不能创建任何新的结点,只能调整树中结点指针的指向. 2 思路和方法 在二叉搜索树中,每个结点都有两个分别指向其左.右子树的 ...

  4. 剑指offer 面试题36.二叉搜索树与双向链表

    中序递归,一个pre节点记录前一个节点 /* struct TreeNode { int val; struct TreeNode *left; struct TreeNode *right; Tre ...

  5. JAVA集合类(代码手写实现,全面梳理)

    参考网址:https://blog.csdn.net/weixin_41231928/article/details/103413167 目录 一.集合类关系图 二.Iterator 三.ListIt ...

  6. [CareerCup] 17.13 BiNode 双向节点

    17.13 Consider a simple node-like data structure called BiNode, which has pointers to two other node ...

  7. 九度-剑指Offer

    二维数组中的查找 分析:既然已经给定了每一行从左至右递增,那么对于每一行直接二分查找即可,一开始还想着每一列同样查找一次,后来发现每一行查找一遍就能够遍历所有的元素了. #include <cs ...

  8. JDK1.8 HashMap--treeifyBin()方法

    /*树形化*/ final void treeifyBin(Node<K,V>[] tab, int hash) { int n, index; Node<K,V> e;// ...

  9. HashMap源码分析(Java8)

    1. HashMap public class HashMap<K,V> extends AbstractMap<K,V> implements Map<K,V>, ...

随机推荐

  1. 转!!java反射机制

    Java 反射机制 基本概念 在Java运行时环境中,对于任意一个类,能否知道这个类有哪些属性和方法?对于任意一个对象,能否调用它的任意一个方法? 答案是肯定的. 这种动态获取类的信息以及动态调用对象 ...

  2. hiho_1290_demo_day

    题目大意 一个MxN的矩阵,矩阵中的有些方格中有障碍物,有些没有,有一个机器人从左上角出发,它只能有两种移动方式:一直向右移动,直到遇到障碍物:一直向下移动,直到遇到障碍物.     现在可以将矩阵中 ...

  3. iOS开发 字符串MD5加密

    /*** MD5 ***/ #define CC_MD5_DIGEST_LENGTH    16          /* digest length in bytes */ #define CC_MD ...

  4. java里的基本数据类型

    java里一共有八大数据类型 boolean(未定) char(2字节) byte(1字节) short(2字节) int(4字节) long(8字节) float(4字节) double(8字节), ...

  5. 获取AVCaptureSession samplebuffer 一像素的 rgb值

    获取AVCaptureSession samplebuffer 一像素的 rgb值 typedef unsigned char byte; typedef struct RGBPixel{ byte ...

  6. Java开发Maven环境配置和介绍

    最近很火热的12306的订票软件go-home,我也下载了一份下来了,使用了一下,也从svn中把代码down下来了,但是在eclipse中竟然出错了,依赖的jar包都没有找到,后来才知道人家是用mav ...

  7. 关于js中变量声明和作用域的理解

    1. var是声明一个变量:虽然声明了这个变量,但在存入值之前,它的初始值是 undefined:2.全局变量:拥有全局作用域,在js代码中的任何地方都是有定义的:3.局部变量:在函数内声明的变量只在 ...

  8. --专访雷果国: 从1.5K到18K 一个程序员的5年成长之路--

    导语:今年三月份,在CSDN博客和新浪微博上有一篇<从1.5K到18K,一个程序员的5年成长之路>被众人分享和传阅,这篇博文首先介绍了作者自学之初薄弱的基础,然后通过流水账形式分享了那个从 ...

  9. python与unicode

    Unicode是一种在计算机上使用的字符编码,是为了解决传统的字符编码方案的局限而产生的,它为每种语言中的每个字符设定了统一并且唯一的二进制编码,以满足跨语言.跨平台进行文本转换.处理的要求. Uni ...

  10. androidStudio中如何加载字体资源?

    在android中字体的格式总是不能尽善尽美的显示出来 ,  于是要求我们使用一些有美感的字体,加载的方式(就像HTML的字体一样),我们需要通过加载字体的方式来使用android中不曾提供的字体; ...