中国IT动力,最新最全的IT技术教程
最新100篇 | 推荐100篇 | 专题100篇 | 排行榜 | 搜索 | 在线API文档 | 网通镜像
首 页 | 程序开发 | 操作系统 | 软件应用 | 图形图象 | 网络应用 | 精文荟萃 | 教育认证 | 硬件维护 | 未整理篇 | 站长教程
ASP JS PHP工程 ASP.NET 网站建设 UML J2EESUN .NET VC VB VFP 网络维护 数据库 DB2 SQL2000 Oracle Mysql
服务器 Win2000 Office C DreamWeaver FireWorks Flash PhotoShop 上网宝典 CorelDraw 协议大全 网络安全 微软认证
硬件维护  CPU  主板  硬盘  内存  显卡  显示器  键盘鼠标  声卡音箱  打印机  机箱电源  BIOS  网卡  C#  Java  Delphi  vs.net2005
  当前位置:> 程序开发 > 编程语言 > 综合其它
完全二杈树的层次序遍历
作者:未知 时间:2005-07-27 23:18 出处:CSDN 责编:chinaitpower
              摘要:完全二杈树的层次序遍历

完全二杈树的层次序遍历

树的遍历通常是从父结点到子结点或子结点到父结点的顺序(前序,后序,中序),如果要实现同一层的所有元素用一般的方法要用堆栈来做,而且实现非常复杂。这里提供一种特别的遍历方法。

我们先按从上到下从左到右的顺序给二杈树的元素编号:第一层的一个元素编1号,第二层左边第一个编2号,第二个编3号,第三层左边第一个编1号,第二个编2号,第三个编3号第四个编4号……大致情况如下:

1

2,3

4,5,6,7

8,9,10,11,12,13,14,15

16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31

……

从后的情形很清楚了,只要能知道第几个元素在哪很容易就能实现层次序的遍历。我们现在关注的是如何能知道24号在哪很快就能找到它?

我才用了如下方法,将编号除以2的余数是1还是0来确定它在父结点的左边还是右边,余数是1在右点是0在左边,再将商除以2看余数。如此循环直到结果等于1为止。我用vector将每次的结果保存起来,以make_path函数来实现。

     int make_path(int index)

     {

 

         serial.clear();

         int t = index;

         while ( t != 1)

         {

              if( t % 2 == 0)

              {

                   serial.push_back(t % 2);                 

              }

              else

              {

                   serial.push_back(t % 2);

                   t--;

              }

              t/=2;

         }

 

         return 0;

 

    }

       思路很简单,就是把编号除以二把余数存入serial 它的定义如下:

     vector<int> serial;

再跟据生成的路径寻找到指定原素:

     int go_to(int index)

     {

         pcurrent= root;

         if(index == 1)

              return 0;

         make_path(index);

         for( vector<int>::reverse_iterator iter = serial.rbegin();

              iter != serial.rend();

              iter ++)

         {

              if(*iter)

              {

                   pcurrent = pcurrent->right;

              }

              else

              {

                   pcurrent = pcurrent->left;

              }

         }

         return 0;

}

如果serial中是0就访问他的左结点,否则就是右结点。Pccurrent是访问的当前节点的指针。

下面是插入算法,值得它是个和go_to想似的算法,不同就是如果即将访问的子节点的指针是NULL的话即认为找到,插入。还有就是当树为空时的插入。

     int insert(T data)

     {

         pcurrent = root;

         if(root)

         {

              make_path(m_count+1);

              for( vector<int>::reverse_iterator iter = serial.rbegin();

                   iter != serial.rend();

                   iter ++)

              {

                   if(!*iter)

                   {

                       if(pcurrent->left)

                            pcurrent = pcurrent->left;

                       else

                       {

                            pcurrent->left = new Node<T>(data,pcurrent);

                            break;

                       }

                   }                     

                   else

                   {

                       if(pcurrent->right)

                            pcurrent = pcurrent->right;

                       else

                       {

                            pcurrent->right = new Node<T>(data,pcurrent);

                            break;

                       }

                   }

              }

         }

         else

         {

              root = new Node<T>(data);

         }

         m_count ++;

         return m_count ;

 

     }

T是用模版定义的一个类型参数,用它来实现算法的数据无关性。

下面遍厉就很简单了:

     for( int i = 1; i <= tree.m_count ; i++)

     {

         cout << tree[i] ;

         if( i+1 == pow(2,c))

         {

              cout << endl;

              c++;

         }

         else

              cout << ",";

}

if是为了考虑换行,因为每一行的第一个是2c次方所以如果打印的是2c次方减1的话换行。

下面是完整的原代码:

// bintree.cpp : 定义控制台应用程序的入口点。

//

 

#include "stdafx.h"

#include "iostream"

#include "vector"

#include "conio.h"

#include "cmath"

 

 

using namespace std;

template<class T>

class Node

{

    

private:

     Node();

public:

     T data;

     Node *left;

     Node *right;

     Node *parent;

     Node(int n):left(NULL),right(NULL),parent(NULL),data(n)

     {

     }

     Node(int n,Node *p):left(NULL),right(NULL),parent(p),data(n)

     {

     }

     operator=(const int &n)

     {

         data = n;

     }

     Node &operator=(const Node &n)

     {

         data = n.data;

         return *this;

     }

     bool operator>(const Node &n)

     {

         return data > n.data;

     }

};

 

template<class T>

class Tree

{

public:

     Node<T> *root;

     Node<T> *pcurrent;

     vector<int> serial;

     int m_count;

 

     Tree():root(NULL),pcurrent(NULL),m_count(0)

     {

     }

     ~Tree()

     {

         remove();

     }

     int go_to(int index)

     {

         pcurrent= root;

         if(index == 1)

              return 0;

         make_path(index);

         for( vector<int>::reverse_iterator iter = serial.rbegin();

              iter != serial.rend();

              iter ++)

         {

              if(*iter)

              {

                   pcurrent = pcurrent->right;

              }                     

              else

              {

                   pcurrent = pcurrent->left;

              }

         }

         return 0;

     }

     T operator[](int index)

     {

         go_to(index);

         return pcurrent->data;

 

     }

     int insert(T data)

     {

         pcurrent = root;

         if(root)

         {

              make_path(m_count+1);

              for( vector<int>::reverse_iterator iter = serial.rbegin();

                   iter != serial.rend();

                   iter ++)

              {

                   if(!*iter)

                   {

                       if(pcurrent->left)

                            pcurrent = pcurrent->left;

                       else

                       {

                            pcurrent->left = new Node<T>(data,pcurrent);

                            break;

                       }

                   }                     

                   else

                   {

                       if(pcurrent->right)

                            pcurrent = pcurrent->right;

                       else

                       {

                            pcurrent->right = new Node<T>(data,pcurrent);

                            break;

                       }

                   }

              }

         }

         else

         {

              root = new Node<T>(data);

         }

         m_count ++;

         return m_count ;

 

     }

     int remove()

     {

         rec_del(root);

         m_count=0;

         return 0;

 

     }

     int rec_del( Node<T>* &p)

     {

         if(!p)

              return 1;

         if(p->left)

              rec_del(p->left);

         if(p->right)

              rec_del(p->right);

         delete p;

         p = NULL;

         return 0;

 

     }

     int sort( Node<T> *p)

     {

         Node<T> t(p->data);

         if(p->parent)

         {

              if(*p > *p->parent)

              {

                   *p = *p->parent;

                   *p->parent = t;

              }

         }

         return 0;

     }

     int sort(int index)

     {

         go_to(index);

         sort(pcurrent);

         return 0;

 

     }

     int make_path(int index)

     {

 

         serial.clear();

         int t = index;

         while ( t != 1)

         {

              if( t % 2 == 0)

              {

                   serial.push_back(t % 2);                 

              }

              else

              {

                   serial.push_back(t % 2);

                   t--;

              }

              t/=2;

         }

 

         return 0;

 

     }

 

    

 

};

int _tmain(int argc, _TCHAR* argv[])

{

     int n;

     int in;

     Tree<int>  tree;

     cin >> n;

     tree.remove();

         for( int i = 1; i <= n ; i ++)

     {

         cin >> in;

         tree.insert(in);

     }

     int layer = 1;

     for( int i = n; i > 0; i--)

     {

         tree.sort(i);

     }

     int c= 1;

     for( int i = 1; i <= tree.m_count ; i++)

     {

         cout << tree[i] ;

         if( i+1 == pow(2,c))

         {

              cout << endl;

              c++;

         }

         else

              cout << ",";

     }

 

    

     getch();

 

     return 0;

}

 

编译平台: windows xp sp2,VC++2003


关闭本页
 
首页 | 投资与合作 | 服务条款 | 隐私政策 | 收藏本站 | 设为首页 | 新用户注册 | 免责声明 | 使用帮助
Copyright ©2005-2008 chinaitpower.com All rights reserved. www.chinaitpower.com 版权所有