对二叉树进行排序

时间:2015-09-30 02:50:18

标签: c++ algorithm sorting binary-tree

我编写了一个简单的二叉树,使用结构和几个函数来添加,搜索,查找最小值和最大值,删除节点以及销毁节点,问题是我一直在使用递归并以同样的方式处理它,我很难理解我的排序算法的功能是否足够有效。

整个代码是:

#include<iostream>
using namespace std;

/*
  This is a very simple example demonstrating a very basic binary tree to be 
  implemented using structurs, later on I would like to create this by using
  classes, but for now, structures and pointers would suffice
*/


/*
 * The node is created in here, notice how the pointer has the ability to 
 * self reference to 2 different positions, this means that there is the ability
 * to store to 2 different branches of memory
 *
 */

struct node{
  int key_value;
  node * p_left;
  node * p_right;
};

/*
 *
 * This is the creation of the add function that will add to the linked list
 *
 */

node* add(node * p_tree, int key) {
  //--The base case of the recursive function will be placed in here
  //--since binary trees are recursive in nature and linked data structures
  //--are as a whole in terms of space and memory, the recursive function will
  //--suffice for most cases involving binary trees.
  //--In this case, if the given parameter is null, we create the tree
  //--by allocating the necessary memory space
  if (p_tree == NULL) {
    node * pnew_tree = new node;
    pnew_tree->p_left = NULL;
    pnew_tree->p_right = NULL;
    pnew_tree->key_value = key;
    return pnew_tree;
  }// end of base case

  //--Depending of the value of the node, we determine if we will add to the left side or the right side of the subtree
  if (key < p_tree->key_value){
    // if it is less than the value, we add to the left
    p_tree->p_left = insert(p_tree->p_left, key);
  }
  else{
    p_tree->p_right = insert(p_tree->p_right, key);
  }
  return p_tree;
} // end of function


/*
 *  
 * This is where the search function will be created
 * in here the function will go over all the subtrees untill the one with the necessary key is returned
 * again, this uses recursive functions doing things step by step:
 * 
 * First: Look to see if the given tree node is empty(NULL) if yes then return NULL
 * 
 * Second: If we find the key by referencing the key value, then we are done and return that particular tree
 *
 * Third: Otherwise, look into the left and right sides of the tree making recursive calls to this very same function until
 *        the one that we are looking for is found.
 * 
 */ 

node* search(node *p_tree, key) {
  //--First:
  if (p_tree == NULL) { return NULL; }

  //--Second:
  else if (p_tree->key_value = key) { return p_tree; }

  //--Third:
  else if(key < p_tree->key_value) {
    search(p_tree->p_left, key); //--Thus it looks into the left with the same recursive algorithm
  }
  else {
    search(p_tree->p_right, key);
  }
}//--End of recursive search function

/*
 *
 * Easiest function to implement, since the delete key is used being that the whole concept falls inside memory being allocated to the
 * list via the creation of new nodes(this means using the new keyword to allocate memory, much like creating new objects in other languages)
 *
 * First: Check to see if passed tree is not null, if not null destroy the left and right subtree using the same function
 *        else nothing.
 * 
 * NOTE: The return value is set to void since it returns nothing back to the list
 *
 */
void destroy_node(node* p_tree) {
  //--First
  if (p_tree != NULL) {
    destroy(p_tree->p_left);
    destroy(p_tree->p_right);
    cout << endl;
    cout << "Destroying left subtree node" << endl;
    cout << "Destroying right subtree node" << endl;
    cout << "Deleting the entire node: " << p_tree->key_value << endl;
    cout << endl;
    delete p_tree;
  }
}//--End of recursive destroy function



/*
 *
 * Finding the max value is simple, we evaluate the left and right node and use base cases to see which node to return
 * Why just right?
 * looking back at the theory behind binary trees, the tree on the right is always the biggest element. That is how trees are normally sorted.
 * there is no need to look at the keys, the code will sort out by itself in this space since if it is not null it will return the highest.
 */
node* return_max(node* p_tree) {
  if (p_tree == NULL) {
    return NULL;
  }
  if (p_tree->p_right == NULL) {
    return p_tree;
  }
  return return_max(p_tree->p_right);
} //--End of return max recursive function


/*
 *
 * Max node, basically the opposite of the avobe taking advantage of the fact that the left node is lesser
 * recursion will be used again
 *
 */

node* return_min(node* p_tree){
  if (p_tree == NULL) {
    return NULL;
  }
  if(p_tree->p_left == NULL) {
    return p_tree;
  }
  return return_min(p_tree->p_left);
}//--End of recursive return min function

/*
 *
 * We need a remove max function in order to properly remove the biggest node in case it is found, that way we can implement a recursive
 * algorithm inside the  function in charge of removing the node we want, we can simply remove the node by using delete or destroy once we
 * find it because that would only destroy the entire tree! No no, that is not good.
 *
 */
node* remove_max_node(node* p_tree, node* p_max_node) {
  if (p_tree == NULL) { return NULL;}

  if (p_tree == p_max_node) {
    return p_max_node->p_left; //--Because the left one is lesser
  }
  //--Now for the recursive call, implementing this means that we will remove from the node on the right
  //--basing us on the sense that the right tree is the highest one, it will go then from top to bottom
  p_tree->p_right = remove_max_node(p_tree->p_right, p_max_node);
  //--return the tree after the changes in the addresses have been conducted properly
  return p_tree;

}




/*
 * 
 *
 *
 *
 * Removing from a tree is also simple based on the recursive nature of the element being discussed
 *
 * First: Check to see if the tree is null, if yess, return null
 *
 */
node* removeN(node* p_tree, int key) {
  //--First:
  if (p_tree == NULL) { return NULL;}
  //--Second
  if(p_tree->key_value == key) {
    //--Third:
    if (p_tree->p_left == NULL) {
      node* p_right_sub = p_tree->p_right;
      delete p_tree;
      return p_right_sub;
    }
    if (p_tree->p_right == NULL) {
      node* p_left_sub = p_tree->p_left;
      delete p_tree;
      return p_left_sub;
    }

    node* p_maxN = return_max(p_tree->p_left);
    p_maxN->p_left = remove_max_node(p_tree->p_left, p_max_node);
    p_maxN->p-right = p-tree->p_right;
    delete p_tee;
    return p_max_node;
  }
  else if(key < p_tree->key_value) {
    p_tree->p-left = removeN(p_tree->p_left, key);
  }
  else {
    p_tree->p_right = removeN(p_tree->p_right, key);
  }
  //--After all  changes have been done
  return p_tree;
}

/*
 *
 * The entire implementation is sorted when calling return min and max
 * 
 *
 */
 node* sortedN(node* p_tree){
  if (p_tree == NULL){return NULL;}

  return sortedN(return_max(p_tree));
 }





int main(int argv, char* []){

  cout << "This is merely a test" << endl;
  return 0;
}

我的理解是,我定义其他函数的方式最初已经按照我正在使用指针的新方式排序并返回节点本身的状态。也许我认为我的排序功能有效是错误的。我一整天都在这里,想不出更好的方法,我的大部分代码都是为了我的理解和书籍的帮助而编写的,我的导师也没有多少帮助所以我来到这里寻求一些智慧。

0 个答案:

没有答案