标签:
本文学习的是:二叉搜索(排序)树的普通操作
包括:插入,删除,查找,前序遍历,中序遍历,后序遍历,树的最大深度,最小深度,最大值,最小值和节点个数。
首先需要清楚二叉搜索树的定义:
二叉搜索树或者是一棵空树,或者是具有下列性质的二叉树:
(1)若左子树不空,则左子树上所有结点的值均小于它的根结点的值;
(2)若右子树不空,则右子树上所有结点的值均大于它的根结点的值;
(3)左、右子树也分别为二叉排序树;
(4)没有键值相等的节点。
图1
如图1所示,就是一棵二叉搜索树!
下面对程序进行解析:
(0)前提准备:
做了一个结构体,方便操作。
<span style="font-family:SimSun;font-size:18px;">struct node { int value; struct node* left; struct node* right; }; typedef struct node NODE; typedef struct node* PNODE; </span>
(1)插入函数insert_node(PNODE *n int value)
思路:传入插入函数的参数是(1)指向tree的指针(2)要插入的数值value
如果树为空,那么就新建一棵树,让其根(root)为要插入的数值value
如果树不为空,那么让value与原来树的根(相对根)进行比较,如果比它小,必然要插入到左子树中,如果比它大,必然要插入到右子树中。这里就要用到递归,将指向左子树的指针更改为参数值,进行对insert_node函数的调用,同理右子树。
这里注意二叉搜索树的第(4)条,如果要插入的数值在tree中已经存在,那么什么也不做,直接返回。
C语言代码:
(1)插入节点函数
<span style="font-family:SimSun;font-size:18px;">void insert_node (PNODE* n,int value) { if(*n == NULL) { new_node(n,value); }else if ((*n)->value == value){ return ; }else if (value < (*n)->value) { insert_node(&((*n)->left),value); }else { insert_node(&((*n)->right),value); } }</span>(2)新建节点函数
<span style="font-family:SimSun;font-size:18px;">void new_node (PNODE* n,int value) { *n = (PNODE)malloc(sizeof(NODE)); if(*n != NULL) { (*n)->value = value; (*n)->left = NULL; (*n)->right = NULL; } }</span>
思路:
(1)如果要删除的节点是叶子节点:比如我要删除的是10(或者30,或者50)
图1
将20这个节点指向10这个节点的指针设为NULL,然后释放它。
(2)如果要删除的节点只有右节点:我要删除的是20
图2
将30这个节点顶替20这个位置,然后释放它
(3)如果要删除的节点只有左节点:同理(2)(就不上图了。)
(4)如果要删除的节点既有左节点(左子树)又有节点(子树):我要删除的是20
图1
可以在20节点的左子树中找最大的值或者在右子树中找到最小的值,顶替20的位置,释放它,然后再调整树。
在编码的过程中可以将第一种情况与第二种情况合并。
传入删除函数的参数是(1)指向tree的指针(2)要删除的数值value
C语言代码:
(1)判断要删除哪一个
void delet_node(PNODE* n,int value) { if(*n == NULL) { return ; } if((*n)->value == value) { deletenode(n); }else if(value < (*n)->value) { delet_node(&((*n)->left),value); }else { delet_node(&((*n)->right),value); } }如果树非空,对当前节点与要删除的节点做对比,如果不等,进行左右比较,如果相等要进行删除工作。
(2)判断如果删
void deletenode(PNODE* n) { PNODE temp = NULL; if(n == NULL) { return ; } if((*n)->right == NULL) { temp = *n; *n = (*n)->left; free_node(n); }else if((*n)->left == NULL) { temp = *n; *n = (*n)->right; free_node(n); }else { for(temp == (*n)->right;temp->left !=NULL;temp = temp->left); temp->left = (*n)->left; temp = (*n); *n = (*n)->right; free_node(&temp); } }这里即对如上4种情况讨论(合并为3种)的代码实现。
(3)正式删除
void free_node(PNODE* n) { if(*n !=NULL) { free(*n); *n = NULL; } }这里是真正的删除节点操作。
(3)查找find_node(PNODE n,int value)
有了上面两个函数的基础,再编写查找就不是很困难了,还是使用递归。但要注意,前两个不需要返回值,所以都设为void类型,但是查找要有返回值,是否为NULL,所以函数返回类型是PNODE
C语言代码:
PNODE find_node (PNODE n,int value) { if (n == NULL) { return NULL; }else if (n->value ==value) { return n; }else if (value <= n->value) { return find_node(n->left,value); }else { return find_node(n->right,value); } }
#include<stdio.h> #include<malloc.h> #include<stdlib.h> struct node { int value; struct node* left; struct node* right; }; typedef struct node NODE; typedef struct node* PNODE; void new_node (PNODE* n,int value) { *n = (PNODE)malloc(sizeof(NODE)); if(*n != NULL) { (*n)->value = value; (*n)->left = NULL; (*n)->right = NULL; } } void free_node(PNODE* n) { if(*n !=NULL) { free(*n); *n = NULL; } } void deletenode(PNODE* n) { PNODE temp = NULL; if(n == NULL) { return ; } if((*n)->right == NULL) { temp = *n; *n = (*n)->left; free_node(n); }else if((*n)->left == NULL) { temp = *n; *n = (*n)->right; free_node(n); }else { for(temp == (*n)->right;temp->left !=NULL;temp = temp->left); temp->left = (*n)->left; temp = (*n); *n = (*n)->right; free_node(&temp); } } PNODE find_node (PNODE n,int value) { if (n == NULL) { return NULL; }else if (n->value ==value) { return n; }else if (value <= n->value) { return find_node(n->left,value); }else { return find_node(n->right,value); } } void insert_node (PNODE* n,int value) { if(*n == NULL) { new_node(n,value); }else if ((*n)->value == value){ return ; }else if (value < (*n)->value) { insert_node(&((*n)->left),value); }else { insert_node(&((*n)->right),value); } } void delet_node(PNODE* n,int value) { if(*n == NULL) { return ; } if((*n)->value == value) { deletenode(n); }else if(value < (*n)->value) { delet_node(&((*n)->left),value); }else { delet_node(&((*n)->right),value); } } void Pre_order_traversal(PNODE n) { if(n != NULL) { printf ("%d ",n->value); Pre_order_traversal(n->left); Pre_order_traversal(n->right); } } void In_order_traversal(PNODE n) { if(n != NULL) { In_order_traversal(n->left); printf ("%d ",n->value); In_order_traversal(n->right); } } void Post_order_traversal(PNODE n) { if(n != NULL) { Post_order_traversal(n->left); Post_order_traversal(n->right); printf ("%d ",n->value); } } int get_max_depth(PNODE n) { int left = 0; int right = 0; if(n == NULL) { return 0; } if(n->left != NULL) { left=1 + get_max_depth(n->left); } if(n->right != NULL) { right=1 + get_max_depth(n->right); } return (left > right ? left : right); } int get_min_depth(PNODE n) { int left = 0; int right = 0; if(n == NULL) { return 0; } if(n->left != NULL) { left = 1 + get_min_depth(n->left); } if(n->right != NULL) { right = 1 + get_min_depth(n->right); } return (left > right) ? right : left; } int get_max_value(PNODE n) { if(n == NULL) { return 0; } if(n->right == NULL) { return n->value; }else { return get_max_value(n->right); } } int get_min_value(PNODE n) { if(n == NULL) { return 0; } if(n->left == NULL) { return n->value; }else { return get_min_value(n->left); } } int get_num_nodes(PNODE n) { int left = 0; int right = 0; if(n == NULL) { return 0; } if(n->left != NULL) { left = 1 + get_num_nodes(n->left); } if(n->right != NULL) { right = 1 + get_num_nodes(n->right); } return left+right+1; } int main() { char buf[50]; int option; PNODE tree = NULL; PNODE node = NULL; while(1) { printf ("\n-----------------------\n"); printf ("Options are:\n\n"); printf ("0 Exit\n"); printf ("1 Insert node\n"); printf ("2 Delet node\n"); printf ("3 Find node\n"); printf ("4 Pre order traversal\n"); printf ("5 In order traversal\n"); printf ("6 Post order traversal\n"); printf ("7 Max depth\n"); printf ("8 Min depth\n"); printf ("9 Max value\n"); printf ("10 Min value\n"); printf ("11 Node count\n\n"); printf ("\n-----------------------\n"); printf ("Select an option: "); scanf ("%d",&option); printf ("\n------------------------\n"); if (option < 0 || option > 11) { printf ("Invalid option!"); continue; } switch(option) { case 0: return 0; case 1: printf ("Enter number to insert: "); scanf ("%d",&option); printf ("\n\n"); insert_node (&tree,option); break; case 2: printf ("Enter number to delet: "); scanf ("%d",&option); printf ("\n\n"); delet_node (&tree,option); break; case 3: printf ("Enter number to find: "); scanf ("%d",&option); printf ("\n\n"); node = find_node (tree,option); if (node != NULL) { printf ("Found node\n\n"); }else { printf ("Couldn't find node\n\n"); } break; case 4: printf ("Pre order traversal: "); printf ("\n\n"); Pre_order_traversal(tree); break; case 5: printf ("In order traversal: "); printf ("\n\n"); In_order_traversal(tree); break; case 6: printf ("Post order traversal: "); printf ("\n\n"); Post_order_traversal(tree); break; case 7: printf ("Max depth is %d\n\n",get_max_depth(tree)); break; case 8: printf ("Min depth is %d\n\n",get_min_depth(tree)); break; case 9: printf ("Max value is %d\n\n",get_max_value(tree)); break; case 10: printf ("Min value is %d\n\n",get_min_value(tree)); break; case 11: printf ("Node count is %d\n\n",get_num_nodes(tree)); break; } } return 0; }
标签:
原文地址:http://blog.csdn.net/qq_28684963/article/details/51240366