1 构建思路

先将任意的二叉查找树转化为类似于链表的树,使之成为主链或者主干;然后进行适当的旋转。

2 旋转

3 代码


#include <iostream>#include<math.h>
#include<stdlib.h>
#include<list>
#include<stack>
#include<queue>
using namespace std;//栈实现
template<class T>
class Stack : public stack<T>
{
public:T pop() {T tmp = stack<T>::top();stack<T>::pop();return tmp;}
};//队列实现
template<class T>
class Queue : public queue<T>
{
public:T dequeue() {T tmp = queue<T>::front();queue<T>::pop();return tmp;}void enqueue(const T& el) {queue<T>::push(el);}
};//树节点类
template<class T>
class Node
{
public:Node() :left(NULL), right(NULL) {}Node(const T& e, Node<T>* l = NULL, Node<T>*r = NULL) :data(e), left(l), right(r) {}~Node() {}T data;Node* left;Node* right;
};//二叉查找树的实现类
template<class T>
class BST
{
public:BST() :root(NULL), count(0) {}BST(T* a, int len);    //根据数组中的数据构造树,调试测试用~BST() {clear();}bool isEmpty() const {return NULL == root;}void clear() {clear(root);root = NULL;}unsigned int count;void insert(const T&);       //插入void inorder() {//深度遍历之中序树遍历inorder(root);}void breadthFirst();     //广度优先遍历virtual void visit(Node<T>* p) {cout << p->data << ' ';}protected:Node<T>* root; //根节点void clear(Node<T>*);void inorder(Node<T>*);
};//根据数组中的内容构造树
template<class T>
BST<T>::BST(T* a, int len)
{root = NULL;count = 0;for (int i = 0; i < len; i++) {insert(a[i]);}
}//清除节点p及其子节点
template<class T>
void BST<T>::clear(Node<T> *p)
{if (p != NULL) {clear(p->left);clear(p->right);delete p;}count = 0;
}//插入,非递归形式
template<class T>
void BST<T>::insert(const T& el)
{Node<T> *p = root, *prev = NULL;while (p != NULL) {  // find a place for inserting new node;prev = p;if (el < p->data)p = p->left;else p = p->right;}if (root == NULL)    // tree is empty;root = new Node<T>(el);else if (el < prev->data)prev->left = new Node<T>(el);else prev->right = new Node<T>(el);++count;
}//广度优先遍历(从上到下,从左到右,一层一层的向下访问)
template<class T>
void BST<T>::breadthFirst()
{Queue<Node<T>*> m_queue;   //要理解这里为什么要用队列,这个队列的作用是把下一层的数据放到本层数据的后面Node<T>* p = root;if (p != NULL) {m_queue.enqueue(p);while (!m_queue.empty()) {p = m_queue.dequeue();visit(p);if (p->left != NULL)m_queue.enqueue(p->left);if (p->right != NULL)m_queue.enqueue(p->right);}}
}//中序遍历,递归实现
template<class T>
void BST<T>::inorder(Node<T> *p)
{if (p != NULL) {inorder(p->left);visit(p);inorder(p->right);}
}template<class T>
class DswBST : public BST<T>
{
public:DswBST(T* a, int len);    //根据数组中的数据构造树,调试测试用void dswBalance();
protected:void createBackbone();void creatPerfectTree();void rotateRight(Node<T>* Gr, Node<T>* Par, Node<T>* Ch);void rotateLeft(Node<T>* Gr, Node<T>* Par, Node<T>* Ch);
};template<class T>
DswBST<T>::DswBST(T* a, int len)
{for (int i = 0; i < len; i++) {this->insert(a[i]);}
}template<class T>
void DswBST<T>::dswBalance()
{createBackbone();creatPerfectTree();
}// 二叉查找树转化成主链的过程分析
/**********************************************************************************************
*  5 <-tmp    5                5               5                   5
*   \               \                 \               \                    \
*    10             10              10              10                10
*      \               \                  \               \                    \
*       20            15               15              15                 15
*      /  \               \                 \               \                    \
*     15  30            20              20              20                 20
*          / \               \                  \                \                  \
*        25 40            30 <-tmp       25 <-tmp  23                23
*       /  \                 /  \                /  \               \                 \
*     23    28          25   40           23   30           25               25
*                         /  \                        /  \              \                 \
*                       23   28                  28   40            30 <-tmp    28
*                                                                          / \                \
*                                                                        28 40             30
*                                                                                               \
*                                                                                               40<-tmp
***********************************************************************************************/
template<class T>
void DswBST<T>::createBackbone()
{Node<T> *Gr = 0, *Par = this->root, *Ch = 0;while (Par != 0) {Ch = Par->left;if (Ch != 0) {rotateRight(Gr, Par, Ch);Par = Ch;}else {Gr = Par;Par = Par->right;}// 旋转过程中,如果是绕根节点的右节点旋转时要将根节点置为原根节点的右节点if (Gr == 0)this->root = Ch;}
}/*************************************************************************  子节点Ch围绕父节点Par的右旋转*   Before      After*    Gr          Gr*     \           \*     Par         Ch*    /  \        /  \*   Ch   Z      X   Par*  /  \            /  \* X    Y          Y    Z***********************************************************************/
template<class T>
void DswBST<T>::rotateRight(Node<T>* Gr, Node<T>* Par, Node<T>* Ch)
{if (Gr != 0)Gr->right = Ch;Par->left = Ch->right;Ch->right = Par;
}template<class T>
void DswBST<T>::rotateLeft(Node<T>* Gr, Node<T>* Par, Node<T>* Ch)
{if (Gr != 0)Gr->right = Ch;Par->right = Ch->left;Ch->left = Par;
}template<class T>
void DswBST<T>::creatPerfectTree()
{int n = this->count;if (n < 3) {return; //节点数目小于3不用平衡}int m = (1 << ((int)(log10(n + 1) / log10(2)))) - 1;Node<T> *Gr = 0;Node<T> *Par = this->root;Node<T> *Ch = this->root->right;this->root = this->root->right; //修改root指针// 第一阶段: 左旋n-m次for (int i = 0; i < n - m; i++) {rotateLeft(Gr, Par, Ch);Gr = Ch;Par = Gr->right;if (0 != Par) {Ch = Par->right;}else {break;}}// 第二阶段,进入while循环while (m > 1) {m = m >> 1;Node<T> *Gr = 0;Node<T> *Par = this->root;Node<T> *Ch = this->root->right;this->root = this->root->right;for (int i = 0; i < m; i++) {rotateLeft(Gr, Par, Ch);Gr = Ch;Par = Gr->right;if (0 != Par) {Ch = Par->right;}else {break;}}}
}
int main()
{int a[] = { 5,10,20,15,30,25,40,23,28 };DswBST<int> tree(a, sizeof(a) / sizeof(a[0]));tree.breadthFirst();cout << endl;tree.inorder();cout << endl;tree.dswBalance();tree.breadthFirst();cout << endl;tree.inorder();return 0;
}

DSW算法(《C++数据结构与算法》P200)相关推荐

  1. 算法与数据结构(part1)--算法简介及大O表示法

    学习笔记,仅供参考 文章目录 算法与数据结构--基于python 数据结构和算法简介 算法引入 例题A 算法的概念 例题A的优化 算法效率的衡量 时间复杂度与大O记法 例题A的时间复杂度 如何理解大O ...

  2. python数据结构与算法13_python 数据结构与算法 (13)

    python 数据结构与算法 (13) 选择排序 (Selection sort) 是? 种简单直观的排序算法. 它的? 作原理如 下.? 先在未排序序列中找到最?(?)元素, 存放到排序序列的起始位 ...

  3. 循环首次适应算法_数据结构与算法之2——排序问题

    排序真的是数据结构与算法中的重中之重啊,无论是对编程能力的提升,以后工作后的应用,或者是应对面试的时候都是经常需要用到的.基本的几个经典排序一定要做到滚瓜烂熟,能够做到给你一个具体的排序算法题,一定能 ...

  4. 什么是算法?数据结构与算法概念

    算法的概念 算法是计算机处理信息的本质,因为计算机程序本质上是一个算法来告诉计算机确切的步骤来执行一个指定的任务.一般地,当算法在处理信息时,会从输入设备或数据的存储地址读取数据,把结果写入输出设备或 ...

  5. 尚硅谷01 数据结构与算法_数据结构与算法介绍+稀疏数组

    数据结构与算法的关系 几个实际编程中遇到的问题 要想写出优秀的算法,首先应该能读懂别人写好的算法. 将生活中遇到的实际问题,使用程序来解决 线性结构和非线性结构 线性结构和非线性结构的关系: 数据结构 ...

  6. 【图解数据结构与算法】数据结构与算法知识点整理 Data Structures and Algorithms

    程序=数据结构+算法 数据结构是可以存储和组织数据的命名位置. 算法是用于解决特定问题的一组步骤. 数据结构是指:一种数据组织.管理和存储的格式,它可以帮助我们实现对数据高效的访问和修改. 数据结构 ...

  7. python数据结构算法_数据结构与算法(Python)

    数据结构与算法(Python) Why? 我们举一个可能不太恰当的例子: 如果将最终写好运行的程序比作战场,我们码农便是指挥作战的将军,而我们所写的代码便是士兵和武器. 那么数据结构和算法是什么?答曰 ...

  8. prim算法_数据结构与算法

    根据MOOC上课程总结,文章目录为: 一.引论 数据结构的基本概念 数据的逻辑结构和存储结构 算法及其时间复杂度 时间复杂度及应用 二.线性表 线性表的概念及顺序存储 单链表的概念及其基本操作 建立单 ...

  9. 【蛮力算法】数据结构与算法

    蛮力算法也称为穷举法或暴力法,它是算法设计中最常见的方法之一.蛮力算法的基本思路是对问题的所有可能状态一一测试,直到找到解或将全部可能状态都测试为止. 蛮力算法的概述 蛮力法是一种简单.直接地解决问题 ...

  10. 【数据结构与算法】数据结构与算法基本理论笔记

    数据元素的集合构成一个数据对象,它是针对某种特定的应用. 这里说的数据对象不是面向对象系统中所说的数据对象,后者还需要考虑对象所包含的操作. 内存中组织数据可采用顺序存储和链接存储的方式. 结合外存的 ...

最新文章

  1. Anaconda 使用的一些体验与困惑
  2. symmetric-tree
  3. 算法的性能评价------空间复杂度和时间复杂度
  4. 本地计算机端口流量,计算机和防火墙上的端口及其用途-101问题
  5. Embeded linux之移植iptables
  6. 服务器重启后发现docker-compose的nginx重启失败: Error starting userland proxy: listen tcp 0.0.0.0:80: bind: addres
  7. mysql 排序速度_MySQL排序速度慢而且可能不稳定
  8. struts config xml详细解释
  9. 在cell中自定义分割线的小技巧
  10. openwrt 需要高级浏览器_斐讯K2P刷openwrt设置mentohust
  11. 【计算机图形学】着色简介
  12. 我是如何零基础开始能写爬虫的
  13. iOS小技能:设备ID除了使用_idfa、_idfv 还可使用其他替代方案(使用Keychain 存储UUID)
  14. Win11任务栏大小调整
  15. 二叉排序树基本操作(链表实现)(有错误)
  16. 数仓工具—Hive Beeline(21)
  17. php安装失败,phpcms安装失败怎么办
  18. C++ multimap的简单使用
  19. 电商类产品搜索功能如何优化?
  20. 分享16个Python接单平台,做私活爽歪歪!(附100个爬虫源码)

热门文章

  1. system76_您需要了解有关System76的开源固件项目的知识
  2. Highly Efficient Salient Object Detection with 100K Parameters论文解读
  3. 如何计算近似纳什均衡_纳什-纳什解(Nash-in-Nash Solution)简介
  4. mcinabox运行库下载_mcinabox下载-mcinabox运行库(启动器)官网最新版(附使用教程)v0.1.0-完全实况...
  5. matlab求反函数的函数,关于一个函数的反函数求导问题,一个超复杂函数……急啊!...
  6. vue项目中创建子路由组件
  7. 什么是SHA256?比特币是如何应用SHA256算法的?
  8. CSS 基础篇、绝对有你想要
  9. 基于Android4.0.3的各种工具信息整理(共130个)
  10. 从构建分布式秒杀系统聊聊分布式锁