`
sunxboy
  • 浏览: 2830498 次
  • 性别: Icon_minigender_1
  • 来自: 武汉
社区版块
存档分类
最新评论

二叉树创建及遍历算法(递归及非递归)(转)

阅读更多
java 代码
  1. //二叉树处理头文件   
  2. //包括二叉树的结构定义,二叉树的创建,遍历算法(递归及非递归),   
  3. /*  
  4.  作者:成晓旭  
  5.  时间:2001年10月7日(18:49:38-20:00:00)  
  6.  内容:完成二叉树创建,二叉树的前,中,后序遍历(递归)  
  7.  时间:2001年10月7日(21:09:38-22:09:00)  
  8.  内容:完成二叉树的前,中序遍历(非递归)  
  9.  时间:2001年10月8日(10:09:38-11:29:00)  
  10.  内容:完成查找二叉树的静,动态查找(非递归)  
  11. */  
  12. #include "stdlib.h"  
  13.   
  14. #define MAXNODE 20  
  15. #define ISIZE 8  
  16. #define NSIZE0 7  
  17. #define NSIZE1 8  
  18. #define NSIZE2 15  
  19. //SHOWCHAR = 1(显示字符) SHOWCHAR = 0(显示数字)   
  20. #define SHOWCHAR 1  
  21. //二叉树结构体   
  22. struct BTNode   
  23. {   
  24.  int data;   
  25.  BTNode *rchild;   
  26.  BTNode *lchild;   
  27. };   
  28. //非递归二叉树遍堆栈   
  29. struct ABTStack   
  30. {   
  31.  BTNode *ptree;   
  32.  ABTStack *link;   
  33. };   
  34. char TreeNodeS[NSIZE0] = {'A','B','C','D','E','F','G'};   
  35. char PreNode[NSIZE0] = {'A','B','D','E','C','F','G'};   
  36. char MidNode[NSIZE0] = {'D','B','E','A','C','G','F'};   
  37. int TreeNodeN0[NSIZE1][2] = {{0,0},{1,1},{2,2},{3,3},{4,4},{5,5},{6,6},{7,7}};   
  38. int TreeNodeN1[NSIZE1][2] = {{0,0},{4,1},{2,2},{6,3},{1,4},{3,5},{5,6},{7,7}};   
  39. int TreeNode0[NSIZE1][2] = {{'0',0},{'D',1},{'B',2},{'F',3},{'A',4},{'C',5},{'E',6},{'G',7}};   
  40. int TreeNode1[NSIZE1][2] = {{'0',0},{'A',1},{'B',2},{'C',3},{'D',4},{'E',5},{'F',6},{'G',7}};   
  41. int TreeNode2[NSIZE2][2] = {{'0',0},{'A',1},{'B',2},{'C',3},{'D',4},{'E',5},{'F',6},{'G',7},{'H',8},{'I',9},{'J',10},{'K',11},{'L',12},{'M',13},{'N',14}};   
  42. int InsertNode[ISIZE] = {-10,-8,-5,-1,0,12,14,16};   
  43. //char *prestr = "ABDECFG";   
  44. //char *midstr = "DBEACGF";   
  45. /*  
  46.  二叉树创建函数dCreateBranchTree1()<递归算法>  
  47.  参数描述:  
  48.   int array[]: 二叉树节点数据域数组  
  49.   int i:   当前节点的序号  
  50.   int n:   二叉树节点个数  
  51.  返回值:  
  52.   dCreateBranchTree1 = 新建二叉树的根节点指针  
  53.  备注:  
  54.   根节点 = array[(i+j)/2];  
  55.   左子节点 = [array[i],array[(i+j)2-1]]  
  56.   右子节点 = [array[(i+j)/2+1,array[j]]  
  57. */  
  58. BTNode *dCreateBranchTree1(char array[],int i,int n)   
  59. {   
  60.  BTNode *p; /*二叉树节点*/  
  61.  if(i>=n)   
  62.   return(NULL);   
  63.  p = (BTNode *)malloc(sizeof(BTNode));   
  64.  p->data = array[i];   
  65.  p->lchild = dCreateBranchTree1(array,2*i+1,n);   
  66.  p->rchild = dCreateBranchTree1(array,2*i+2,n);   
  67.  return(p);   
  68. }   
  69. /*  
  70.  二叉树创建函数dCreateBranchTree2()<递归算法>  
  71.  参数描述:  
  72.   int array[]: 二叉树节点数据域数组  
  73.   int i:   当前节点的序号  
  74.   int n:   二叉树节点个数  
  75.  返回值:  
  76.   dCreateBranchTree2 = 新建二叉树的根节点指针  
  77.  备注:  
  78.   根节点 = array[(i+j)/2];  
  79.   左子节点 = [array[i],array[(i+j)2-1]]  
  80.   右子节点 = [array[(i+j)/2+1,array[j]]  
  81. */  
  82. BTNode *dCreateBranchTree2(char array[],int i,int j)   
  83. {   
  84.  BTNode *p; /*二叉树节点*/  
  85.  if(i>j)   
  86.   return(NULL);   
  87.  p = (BTNode *)malloc(sizeof(BTNode));   
  88.  p->data = array[(i+j)/2];   
  89.  p->lchild = dCreateBranchTree2(array,i,(i+j)/2-1);   
  90.  p->rchild = dCreateBranchTree2(array,(i+j)/2+1,j);   
  91.  return(p);   
  92. }   
  93. /*  
  94.  二叉树创建函数dCreateBranchTree3()<非递归算法>  
  95.  已知二叉树的前,中序遍历序列串,构造对应的二叉树  
  96.  <编程思想>:  
  97.   首先,在前序遍历序列中的首元素是二叉树的根节点,接着  
  98.  ,在中序遍历序列中找到此节点,那么在此节点以前的节点必为  
  99.  其左孩子节点,以后的必为其右孩子节点;  
  100.   然后,在中序遍历序列中,根节点的左子树和右子树再分别  
  101.  对应子树前序遍历序列的首字符确定子树的根节点,再由中序  
  102.  遍历序列中根节点的位置分别确定构成它们的左子树和右子树  
  103.  的节点;  
  104.   依次类推,确定二叉树的全部节点,构造出二叉树.  
  105.  参数描述:  
  106.   char *pre:  前序遍历序列  
  107.   char *mid:  中序遍历序列  
  108.   int n:   遍历序列中节点个数  
  109.  返回值:  
  110.   dCreateBranchTree3 = 新建二叉树的根节点指针  
  111. */  
  112. BTNode *dCreateBranchTree3(char *pre,char *mid,int n)   
  113. {   
  114.  BTNode *p;   
  115.  char *t;   
  116.  int left;   
  117.  if(n<=0)   
  118.   return(NULL);   
  119.  p = (BTNode *)malloc(sizeof(BTNode));   
  120.  p->data = *pre;   
  121.  for(t=mid;t<mid+n;t++)   
  122.   if(*t==*pre) break;  /*在中序遍历序列中查找根节点*/  
  123.  left = t - mid;  /*左子树的节点个数*/  
  124.  p->lchild = dCreateBranchTree3(pre+1,t,left);   
  125.  p->rchild = dCreateBranchTree3(pre+1+left,t+1,n-1-left);   
  126.  return(p);   
  127. }   
  128. /*  
  129.  二叉树创建函数CreateBranchTree()<非递归算法>  
  130.  参数描述:  
  131.   int array[]: 二叉树节点数据域数组  
  132.   int n:   二叉树节点个数  
  133.  返回值:  
  134.   CreateBranchTree = 新建二叉树的根节点指针  
  135. */  
  136. BTNode *CreateBranchTree(int array[][2],int n)   
  137. {   
  138.  BTNode *head,*p;   
  139.  BTNode *NodeAddr[MAXNODE]; //节点地址临时缓冲区   
  140.  int i,norder,rorder;   
  141.  head = NULL;   
  142.  printf("二叉树原始数据<新建顺序>:\t");   
  143.  for(i=1;i<=n;i++)   
  144.  {   
  145.   p = (BTNode *)malloc(sizeof(BTNode));   
  146.   if(p==NULL)   
  147.   {   
  148.    printf("\n新建节点时内存溢出!\n");   
  149.    return(NULL);   
  150.   }   
  151.   else  
  152.   {   
  153.    p->data = array[i][0];   
  154.    p->lchild = p->rchild = NULL;   
  155.    norder = array[i][1];   
  156.    NodeAddr[norder] = p;   
  157.    if(norder>1)   
  158.    {   
  159.     rorder = norder / 2/*非根节点:挂接在自己的父节点上*/  
  160.     if(norder % 2 == 0)   
  161.      NodeAddr[rorder]->lchild = p;   
  162.     else  
  163.      NodeAddr[rorder]->rchild = p;   
  164.    }   
  165.    else  
  166.     head = p; /*根节点*/  
  167.    if(SHOWCHAR)   
  168.     printf("%c    ",p->data);   
  169.    else  
  170.     printf("%d    ",p->data);   
  171.   }   
  172.  }   
  173.  return(head);   
  174. }   
  175. //------------------------------递归部分------------------------------   
  176. /*  
  177.  二叉树前序遍历函数dpre_Order_Access()<递归算法>  
  178.  参数描述:  
  179.   BTNode *head: 二叉树的根节点指针    
  180. */  
  181. void dpre_Order_Access(BTNode *head)   
  182. {   
  183.  if(head!=NULL)   
  184.  {   
  185.   if(SHOWCHAR)   
  186.    printf("%c    ",head->data);   
  187.   else  
  188.    printf("%d    ",head->data);   
  189.   dpre_Order_Access(head->lchild); /*递归遍历左子树*/  
  190.   dpre_Order_Access(head->rchild); /*递归遍历右子树*/  
  191.  }   
  192. }   
  193. /*  
  194.  二叉树中序遍历函数dmid_Order_Access()<递归算法>  
  195.  参数描述:  
  196.   BTNode *head: 二叉树的根节点指针    
  197. */  
  198. void dmid_Order_Access(BTNode *head)   
  199. {   
  200.  if(head!=NULL)   
  201.  {   
  202.   dmid_Order_Access(head->lchild); /*递归遍历左子树*/  
  203.   if(SHOWCHAR)   
  204.    printf("%c    ",head->data);   
  205.   else  
  206.    printf("%d    ",head->data);   
  207.   dmid_Order_Access(head->rchild); /*递归遍历右子树*/  
  208.  }   
  209. }   
  210. /*  
  211.  二叉树后序遍历函数dlast_Order_Access()<递归算法>  
  212.  参数描述:  
  213.   BTNode *head: 二叉树的根节点指针    
  214. */  
  215. void dlast_Order_Access(BTNode *head)   
  216. {   
  217.  if(head!=NULL)   
  218.  {   
  219.   dlast_Order_Access(head->lchild); /*递归遍历左子树*/  
  220.   dlast_Order_Access(head->rchild); /*递归遍历右子树*/  
  221.   if(SHOWCHAR)   
  222.    printf("%c    ",head->data);   
  223.   else  
  224.    printf("%d    ",head->data);   
  225.  }   
  226. }   
  227. //------------------------------递归部分------------------------------   
  228. //------------------------------非递归部分------------------------------   
  229. /*  
  230.  二叉树前序遍历函数pre_Order_Access()<非递归算法>  
  231.  参数描述:  
  232.   BTNode *head: 二叉树的根节点指针    
  233. */  
  234. void pre_Order_Access(BTNode *head)   
  235. {   
  236.  BTNode *pt;   
  237.  ABTStack *ps,*top;   
  238.  pt = head;   
  239.  top = NULL;   
  240.  printf("\n二叉树的前序遍历结果<非递归>:\t");   
  241.  while(pt!=NULL ||top!=NULL)  /*二叉树未遍历完,或堆栈非空*/  
  242.  {   
  243.   while(pt!=NULL)   
  244.   {   
  245.    if(SHOWCHAR)   
  246.     printf("%c    ",pt->data);  /*访问根节点*/  
  247.    else  
  248.     printf("%d    ",pt->data);  /*访问根节点*/  
  249.    ps = (ABTStack *)malloc(sizeof(ABTStack));  /*根节点进栈*/  
  250.    ps->ptree = pt;   
  251.    ps->link = top;   
  252.    top = ps;   
  253.    pt = pt->lchild; /*遍历节点右子树,经过的节点依次进栈*/  
  254.   }   
  255.   if(top!=NULL)   
  256.   {   
  257.    pt = top->ptree; /*栈顶节点出栈*/  
  258.    ps = top;   
  259.    top = top->link;   
  260.    free(ps); /*释放栈顶节点空间*/  
  261.    pt = pt->rchild; /*遍历节点右子树*/  
  262.   }   
  263.  }   
  264. }   
  265. /*  
  266.  二叉树中序遍历函数mid_Order_Access()<非递归算法>  
  267.  参数描述:  
  268.   BTNode *head: 二叉树的根节点指针   
  269. */  
  270. void mid_Order_Access(BTNode *head)   
  271. {   
  272.  BTNode *pt;   
  273.  ABTStack *ps,*top;   
  274.  int counter =1;   
  275.  pt = head;   
  276.  top = NULL;   
  277.  printf("\n二叉树的中序遍历结果<非递归>:\t");   
  278.  while(pt!=NULL ||top!=NULL)  /*二叉树未遍历完,或堆栈非空*/  
  279.  {   
  280.   while(pt!=NULL)   
  281.   {     
  282.    ps = (ABTStack *)malloc(sizeof(ABTStack)); /*根节点进栈*/  
  283.    ps->ptree = pt;   
  284.    ps->link = top;   
  285.    top = ps;   
  286.    pt = pt->lchild; /*遍历节点右子树,经过的节点依次进栈*/  
  287.   }   
  288.   if(top!=NULL)   
  289.   {   
  290.    pt = top->ptree; /*栈顶节点出栈*/  
  291.    ps = top;   
  292.    top = top->link;   
  293.    free(ps); /*释放栈顶节点空间*/  
  294.    if(SHOWCHAR)   
  295.     printf("%c    ",pt->data); /*访问根节点*/  
  296.    else  
  297.     printf("%d    ",pt->data); /*访问根节点*/  
  298.    pt = pt->rchild; /*遍历节点右子树*/  
  299.   }   
  300.  }   
  301. }   
  302. /*  
  303.  二叉树后序遍历函数last_Order_Access()<非递归算法>  
  304.  参数描述:  
  305.   BTNode *head: 二叉树的根节点指针    
  306. */  
  307. void last_Order_Access(BTNode *head)   
  308. {   
  309.  BTNode *pt;   
  310.  ABTStack *ps,*top;   
  311.  int counter =1;   
  312.  pt = head;   
  313.  top = NULL;   
  314.  printf("\n二叉树的后序遍历结果<非递归>:\t");   
  315.  while(pt!=NULL ||top!=NULL)  /*二叉树未遍历完,或堆栈非空*/  
  316.  {   
  317.   while(pt!=NULL)   
  318.   {     
  319.    ps = (ABTStack *)malloc(sizeof(ABTStack)); /*根节点进栈*/  
  320.    ps->ptree = pt;   
  321.    ps->link = top;   
  322.    top = ps;   
  323.    pt = pt->lchild; /*遍历节点右子树,经过的节点依次进栈*/  
  324.   }   
  325.   if(top!=NULL)   
  326.   {   
  327.    pt = top->ptree; /*栈顶节点出栈*/  
  328.    ps = top;   
  329.    top = top->link;   
  330.    free(ps); /*释放栈顶节点空间*/  
  331.    printf("%c    ",pt->data); /*访问根节点*/  
  332.    pt = pt->rchild; /*遍历节点右子树*/  
  333.   }   
  334.  }   
  335. }   
  336. /*  
  337.  二叉查找树静态查找函数static_Search_STree()<非递归算法>  
  338.  参数描述:  
  339.   BTNode *head: 二叉查找树的根节点指针  
  340.   int key:  查找关键码  
  341.  返回值:  
  342.   static_Search_STree = 键值为key的节点指针(找到)   
  343.   static_Search_STree = NULL(没有找到)  
  344. */  
  345. BTNode *static_Search_STree(BTNode *head,int key)   
  346. {   
  347.  while(head!=NULL)   
  348.  {   
  349.   if(head->data == key)   
  350.   {   
  351.    printf("\n数据域=%d\t地址=%d\t\n",head->data,head);   
  352.    return(head); /*找到*/  
  353.   }   
  354.   if(head->data > key)   
  355.    head = head->lchild; /*继续沿左子树搜索*/  
  356.   else  
  357.    head = head->rchild; /*继续沿右子树搜索*/  
  358.  }   
  359.  return(NULL); /*没有查找*/  
  360. }   
  361. /*  
  362.  二叉查找树动态查找函数dynamic_Search_STree()<非递归算法>  
  363.  参数描述:  
  364.   BTNode *head:  二叉查找树的根节点指针  
  365.   BTNode **parent: 键值为key的节点的父节点指针的指针  
  366.   BTNode **head:  键值为key的节点指针的指针(找到)或NULL(没有找到)  
  367.   int key:   查找关键码  
  368.  注意:  
  369.   *parent == NULL 且 *p == NULL 没有找到(二叉树为空)  
  370.   *parent == NULL 且 *p != NULL 找到(找到根节点)  
  371.   *parent != NULL 且 *p == NULL 没有找到(叶节点)<可在parent后插入节点>  
  372.   *parent != NULL 且 *p != NULL 找到(中间层节点)  
  373. */  
  374. void dynamic_Search_STree(BTNode *head,BTNode **parent,BTNode **p,int key)   
  375. {   
  376.  *parent = NULL;   
  377.  *p = head;   
  378.  while(*p!=NULL)   
  379.  {   
  380.   if((*p)->data == key)   
  381.    return/*找到*/  
  382.   *parent = *p; /*以当前节点为父,继续查找*/  
  383.   if((*p)->data > key)   
  384.    *p = (*p)->lchild; /*继续沿左子树搜索*/  
  385.   else  
  386.    *p = (*p)->rchild; /*继续沿右子树搜索*/  
  387.  }   
  388. }   
  389. /*  
  390.  二叉查找树插入节点函数Insert_Node_STree()<非递归算法>  
  391.  参数描述:  
  392.   BTNode *head: 二叉查找树的根节点指针  
  393.   int key:  查找关键码  
  394.  返回值:  
  395.   Insert_Node_STree = 1 插入成功  
  396.   Insert_Node_STree = 0 插入失败(节点已经存在)  
  397. */  
  398. int Insert_Node_STree(BTNode *head,int key)   
  399. {   
  400.  BTNode *p,*q,*nnode;   
  401.  dynamic_Search_STree(head,&p,&q,key);   
  402.  if(q!=NULL)   
  403.   return(0);  /*节点在树中已经存在*/  
  404.  nnode = (BTNode *)malloc(sizeof(BTNode)); /*新建节点*/  
  405.  nnode->data = key;   
  406.  nnode->lchild = nnode->rchild = NULL;   
  407.  if(p==NULL)   
  408.   head = p; /*原树为空,新建节点为查找树*/  
  409.  else  
  410.  {   
  411.   if(p->data > key)   
  412.    p->lchild = nnode; /*作为左孩子节点*/  
  413.   else  
  414.    p->rchild = nnode; /*作为右孩子节点*/  
  415.  }   
  416.  return(1); /*插入成功*/  
  417. }   
  418. /*  
  419.  二叉查找树插入一批节点函数Insert_Batch_Node_STree()<非递归算法>  
  420.  参数描述:  
  421.   BTNode *head: 二叉查找树的根节点指针  
  422.   int array[]: 被插入的数据域数组  
  423.   int n:   被插入的节点数目  
  424. */  
  425. void Insert_Batch_Node_STree(BTNode *head,int array[],int n)   
  426. {   
  427.  int i;   
  428.  for(i=0;i<n;i++)   
  429.  {   
  430.   if(!Insert_Node_STree(head,array[i]))   
  431.    printf("\n插入失败<键值为%d的节点已经存在>!\n",array[i]);    
  432.  }   
  433. }   
  434. //------------------------------非递归部分------------------------------   
  435.   
分享到:
评论

相关推荐

Global site tag (gtag.js) - Google Analytics