zoukankan      html  css  js  c++  java
  • 二叉搜索树

    二叉搜索树的简介:

      二叉搜索树通常采取二叉链作为二叉搜索树的存储结构。中序遍历二叉排序树可得到一个关键字的有序序列,一个无序序列可以通过构造一棵二叉排序树变成一个有序序列,构造树的过程即为对无序序列进行排序的过程。每次插入的新的结点都是二叉排序树上新的叶子结点,在进行插入操作时,不必移动其它结点,只需改动某个结点的指针,由空变为非空即可。搜索,插入,删除的复杂度等于树高,O(log(n)),在最坏的情况下,二叉搜索树会退化为一个链表。为了解决这个问题呢,人们又提出了平衡搜索树;

    二叉搜索树的性质:
    1. 每个节点都有一个作为搜索依据的关键码(key),所有节点的关键码互不相同。

    2. 左子树上所有节点的关键码(key)都小于根节点的关键码(key)。

    3. 右子树上所有节点的关键码(key)都大于根节点的关键码(key)。

    4. 左右子树都是二叉搜索树。

    如图:

    /*节点结构*/
    template<class K> struct Node { public: Node(K Key) :key(Key),Left(NULL), Right(NULL) {} K key; Node<K>* Left; Node<K>* Right; };
    /*平衡搜索树类*/
    template<class K> class SearchBinaryTree { public: SearchBinaryTree(K* key,size_t size) :_root(NULL) { for (int i = 0; i < size; ++i) //Creat(_root, key[i]); Creat_Nor(_root,key[i]); } bool Creat(Node<K>*& root, K key); //递归创建 bool Creat_Nor(Node<K>*& root, K key); //非递归创建 bool Delete(Node<K>* root, K key); //删除某一节点 Node<K>* Find(Node<K>* root, K key); //查找某一节点 Node<K>* Find_Nor(Node<K>* root, K key); //非递归查找某一节点 void InOrder(Node<K>* root); //中序遍历 public: Node<K>* _root; };
    /*相关函数的实现*/
    template<class K> bool SearchBinaryTree<K>::Creat(Node<K>*& root,K key) { if (root == NULL) { root = new Node<K>(key); return true; } if (key > root->key) return Creat(root->Right, key); else if (key < root->key) return Creat(root->Left, key); else return false; }
    template
    <class K> bool SearchBinaryTree<K>::Creat_Nor(Node<K>*& root, K key) { if (root == NULL) { root = new Node<int>(key); return true; } Node<K>* prev = NULL; Node<K>* cur = root; while (cur) { prev = cur; if (key > cur->key) { cur = cur->Right; } else if (key < cur->key) { cur = cur->Left; } else return false; } if (prev->key < key) { prev->Right = new Node<K>(key); } else { prev->Left = new Node<K>(key); } return true; }
    template
    <class K> bool SearchBinaryTree<K>::Delete(Node<K>* root, K key) { if (root == NULL) { return false; } Node<K>* prev = NULL; while (root) { if (key > root->key) { prev = root; root = root->Right; } else if (key < root->key) { prev = root; root = root->Left; } else //找的了相应的节点需要删除了 { if (root->Left == NULL) //左为空 { if (prev == NULL) { _root = root->Right; } else if (root->key > prev->key) { prev->Right = root->Right; } else { prev->Left = root->Right; } delete root; } else if (root->Right == NULL) //右为空 { if (prev == NULL) { _root = root->Left; } else if (root->key > prev->key) { prev->Right = root->Left; } else { prev->Left = root->Left; } } else //两边都不为空 { if (prev == NULL) { _root = root; } Node<K>* tmp = root->Right; prev = root; //root 的右子树的最左节点就是 root->right,保证prev始终是tmp的父亲节点 while (tmp->Left) { prev = tmp; tmp = tmp->Left; } swap(tmp->key, root->key); prev == root ? prev->Right = tmp->Right : prev->Left = tmp->Right; } return true; } } return false; }



    当左孩子,右孩子都不为空时,为什么要将右子树的最左孩子与root交换呢,原因是:交换之后能够保证 root->left->key < root->key && root->right->key > root->key  
    从而使得这个搜索二叉树依然有序

    template
    <class K> Node<K>* SearchBinaryTree<K>::Find(Node<K>* root, K key) { if (root == NULL) { return NULL; } if (key > root->key) { return Find(root->Right, key); } else if (key < root->key) { return Find(root->Left, key); } else { return root; } } template<class K> Node<K>* SearchBinaryTree<K>::Find_Nor(Node<K>* root, K key) { if (root == NULL) { return NULL; } while (root) { if (key > root->key) root = root->Right; else if (key < root->key) root = root->Left; else return root; } return NULL; } template<class K> void SearchBinaryTree<K>::InOrder(Node<K>* root) { if (root == NULL) { return; } InOrder(root->Left); cout << root->key << " "; InOrder(root->Right); }

    二叉搜索树,就到这里了,欢迎参与评论,请不吝赐教~~

     http://www.cnblogs.com/yangecnu/p/Introduce-Binary-Search-Tree.html

  • 相关阅读:
    mysql BETWEEN操作符 语法
    mysql IN操作符 语法
    mysql LIKE通配符 语法
    mysql TOP语句 语法
    mysql DELETE语句 语法
    mysql Update语句 语法
    mysql INSERT语句 语法
    mysql ORDER BY语句 语法
    mysql OR运算符 语法
    mysql AND运算符 语法
  • 原文地址:https://www.cnblogs.com/shihaochangeworld/p/5485217.html
Copyright © 2011-2022 走看看