搜索二叉树的实现

来源:互联网 发布:c语言能做界面吗 编辑:程序博客网 时间:2024/05/19 20:58

本实现只是博主学习数据结构的过程记录,以便以后复习之用。实现上没有任何技巧,而且思维比较混乱,不过这样实践后也是收获了不少。

#include <stdio.h>
#include <stdlib.h>
typedef  int  TREE_TYPE;
typedef enum NODE_TYPE
{
 EM_CHILD_ROOT = 0,
 EM_CHILD_LEFT = 1,
 EM_CHILD_RIGHT = 2
}EM_NODE_TYPE;
typedef struct TREE_NODE{
      struct TREE_NODE *pLeft;
   struct TREE_NODE *pRight;
      TREE_TYPE val;
   EM_NODE_TYPE nodeType;/*0 -root;1--left;2--right*/
}TREE_NOTE_ST;
static TREE_NOTE_ST *s_pHead_ptr = NULL;

int insert(TREE_TYPE val);
void delet(TREE_TYPE val);
void find(TREE_TYPE val);
void tranvers(void);

int  isEmpty(void)
{
 if (NULL ==s_pHead_ptr)
 {
  return 1;
 }
 return 0;
}

int isFull(void){return 0;}

static TREE_NOTE_ST* getOneNode(void)
{
 TREE_NOTE_ST* ptr = NULL;
 ptr = (TREE_NOTE_ST*)malloc(sizeof(TREE_NOTE_ST));
 if(NULL == ptr)
 {
  return NULL;
 }
 else
 {
  return ptr;
 }
}

static void freeOneNode(TREE_NOTE_ST* ptr)
{
  if (NULL == ptr)
  {
   return;
  }
  free(ptr);
}

static TREE_NOTE_ST* leftChild(TREE_NOTE_ST* ptr)
{
    if (NULL == ptr)
    {
  return NULL;
    }

 return ptr->pLeft;
}

static TREE_NOTE_ST* rightChild(TREE_NOTE_ST* ptr)
{
 if(NULL == ptr)
 {
  return NULL;
 }
 return ptr->pRight;
}


int insert(TREE_TYPE val)
{
 TREE_NOTE_ST *pCurNode = NULL;
 TREE_NOTE_ST *pNxtNode = NULL;
 TREE_NOTE_ST *pNewNode = NULL;
    EM_NODE_TYPE  tmpNodeType = EM_CHILD_ROOT;
 
 pNewNode = getOneNode();
 if (NULL == pNewNode)
 {
  return 0;
 }

    /*空树*/
 if (isEmpty())
 {
  pNewNode->val = val;
  pNewNode->pLeft =NULL;
  pNewNode->pRight = NULL;
  pNewNode->nodeType = EM_CHILD_ROOT;
        s_pHead_ptr = pNewNode;
  return 1;
 }

 

 /*只有一个节点*/
 pCurNode = s_pHead_ptr;
 if (NULL == pCurNode->pLeft && NULL == pCurNode->pRight)
 {
 
       if (pCurNode->val < val)
    {
     pCurNode->pRight = pNewNode;
     tmpNodeType = EM_CHILD_RIGHT;
    }
    else
    {
     pCurNode->pLeft = pNewNode;
     tmpNodeType = EM_CHILD_LEFT;
    }
    pNewNode->pLeft = NULL;
    pNewNode->val = val;
    pNewNode->nodeType = tmpNodeType;
    pNewNode->pRight = NULL;
    return 1;
 }

 /*多个节点*/
 pNxtNode = s_pHead_ptr;
    while (NULL != pNxtNode)
    {
       
  pCurNode = pNxtNode;
  if (pCurNode->val < val)
  {
   tmpNodeType = EM_CHILD_RIGHT;
   pNxtNode = rightChild(pCurNode);
  }
  else
  {
   tmpNodeType = EM_CHILD_LEFT;
   pNxtNode = leftChild(pCurNode);
  }
    }
  
   if (EM_CHILD_LEFT == tmpNodeType)
   {
    pCurNode->pLeft = pNewNode;
   }
   else
   {
    pCurNode->pRight = pNewNode;
   }
  
   pNewNode->pLeft = NULL;
   pNewNode->val = val;
   pNewNode->nodeType = tmpNodeType;
   pNewNode->pRight = NULL;

   return 1;
}


void delet(TREE_TYPE val)
{
 TREE_NOTE_ST* pNxtNode = NULL;
 TREE_NOTE_ST* pCurNode = NULL;
 TREE_NOTE_ST* pDelNode = NULL;
 TREE_NOTE_ST* pPreNode = NULL;
 if(isEmpty())
 {
  printf("there are no nodes in this tree\n");
  return;
 }

 /*查找要删除的节点*/
 pNxtNode = s_pHead_ptr;
 while (NULL != pNxtNode)
 {
  
  if (pNxtNode->val > val)
  {
   pPreNode = pNxtNode;
   pNxtNode = leftChild(pNxtNode);
  }
  else if (pNxtNode->val < val)
  {
   pPreNode = pNxtNode;
   pNxtNode = rightChild(pNxtNode);
  }
  else
  {
   pDelNode = pNxtNode;
   break;
  }
 }

 /*判断是非找到要删除的节点*/
 if (NULL == pNxtNode)
 {
  printf("there is no this value in this tree\n");
  return;
 }

 /*要删除的节点是否为叶节点*/
 if (NULL == pDelNode->pLeft && NULL == pDelNode->pRight)
 {
        switch (pDelNode->nodeType)
        {
       case EM_CHILD_ROOT:
                        s_pHead_ptr = NULL;
        break;
      case EM_CHILD_LEFT:
                         pPreNode->pLeft = NULL;
       break;
      case EM_CHILD_RIGHT:
                       pPreNode->pRight = NULL;
      break;
     default:
             break;
        }
  freeOneNode(pDelNode);
 }/*要删除的节点是否只有一个子树*/
 else if ( (NULL != pDelNode->pLeft && NULL == pDelNode->pRight) || (NULL == pDelNode->pLeft && NULL != pDelNode->pRight))
 {
  if (pDelNode->nodeType == EM_CHILD_LEFT)
  {
   pPreNode->pLeft = pDelNode->pLeft;
   pDelNode->pRight->nodeType = EM_CHILD_LEFT;
  }
  else
  {
   pPreNode->pRight = pDelNode->pRight;
   pDelNode->pRight->nodeType = EM_CHILD_RIGHT;
  }
        freeOneNode(pDelNode);
 }
 else/*要删除的节点有两个子树,则删除其右子树中最大值节点,并将用该节点的值去替换本来要被删除节点值*/
 {
  pPreNode =  pDelNode;
  pCurNode =  pDelNode->pLeft;
  pNxtNode =  pDelNode->pLeft;
        /*判断右子树的根节点是否是叶节点*/
  if (NULL == pNxtNode->pLeft && NULL == pNxtNode->pRight)
  {
           pPreNode->pLeft = NULL;
     pDelNode->val = pNxtNode->val;
           freeOneNode(pNxtNode);
     return;
  }
  else if (NULL != pNxtNode->pLeft && NULL == pNxtNode->pRight)/*右子树的根节点只有左子树的情况*/
  {
           pDelNode->pRight = pNxtNode->pLeft;
     pDelNode->val = pNxtNode->val;
     freeOneNode(pNxtNode);
     return;
  }
        /*查找最大大值节点*/
  while ( NULL != pNxtNode->pRight )
  {
   pPreNode = pNxtNode;
   pNxtNode = rightChild(pNxtNode);
   pCurNode = pNxtNode;
  }

  if (NULL == pCurNode->pLeft)/*右子树中最大值节点为叶子节点*/
  {
   pPreNode->pRight = NULL; 
  }
  else/*右子树中最大值节点有左子树*/
  {
            pPreNode->pRight = pCurNode->pLeft;
   pCurNode->pLeft->nodeType = EM_CHILD_RIGHT;
  }
  pDelNode->val = pCurNode->val;
  freeOneNode(pCurNode);

 }
 
   
}


void do_preorder_tree(TREE_NOTE_ST* curNode)
{
  if (NULL == curNode)
  {
   return;
  }
  printf("%d\n",curNode->val);
  do_preorder_tree(curNode->pLeft);
  do_preorder_tree(curNode->pRight);
}
void tranversFirst(void)
{
 TREE_NOTE_ST* pCurNode = NULL;
 pCurNode = s_pHead_ptr;
 do_preorder_tree(pCurNode);
}


int main(int argc, char* argv[])
{
/* insert(3);
 insert(1);
 insert(4);
 insert(0);
 insert(9);
 insert(2);
 tranversFirst();
 delet(4);
 printf("----------------\n");
    tranversFirst();*/

 insert(20);
 insert(16);
 insert(11);
 insert(10);
 insert(14);
 insert(13);
 //insert(15);
 insert(19);
 tranversFirst();
 delet(16);
 printf("----------------\n");
    tranversFirst();
 return 0;
}

0 0
原创粉丝点击