📄 t_list10.hpp
字号:
/* Copyright(C) 2000 by JiangSu Bell Software CO.,LTD. */
/*
****************************************************************************
Content: 10叉树链表处理
Name: T_LIST10.hpp Version: 1.0.0
Created by: CaoGuiRong Date: 2000-08-13
Comment: 10叉树链表处理模板类。 本模板建立唯一性索引
All rights reserved
****************************************************************************
*/
#ifndef __T_LIST10_H__
#define __T_LIST10_H__
#include <string.h>
#include <stdio.h>
/*
class MyString
{
public:
char pcStr[ 256 ] ;
MyString()
{
pcStr[ 0 ] = 0 ;
};
MyString( char* Str )
{
strcpy( pcStr,Str ) ;
};
char *Output()
{
return pcStr ;
}
};
//typedef MyString TYPE ;
*/
/***********************************************************************
Class: T_LIST10 Version: 1.0.0
Created by CaoGuirong Date: 2000-08-13
Implementation (Definition) File: T_LIST10.hpp
Comment: 10叉树链表处理模板类。使用10叉树必须注意:
1,根据索引检索的数据必须是唯一的
2,索引是由'0' ~ '9'之间的字符构成的字符串。不能有其他字符和空格。
3,插入数据时,在链表里面并不申请空间,并没有数据的备份,所以在链
清除以前,在外面不能随便删除数据。
4,链表析构时,只是删除链表的结构,并不清楚数据。所以如果要在外面
删除链表的全部数据,必须在链表析构以前,调用函数RemoveAll() 。
否则,将无法清除链表里面的数据。
***********************************************************************/
/* Modifications
*/
template< class TYPE>
class T_LIST10
{
protected:
struct T_NODE10
{
TYPE* p_data ;
T_NODE10* p_pointer[10];
T_NODE10()
{//constractor
p_data = NULL ;
for( short i = 0 ; i < 10 ; i ++ )
p_pointer[ i ] = NULL ;
};
};
T_NODE10* m_proot;
T_NODE10* m_pcursor;
long m_lcount; //插入的数据数量
long m_lnodecount; //节点数
char m_pcerr[ 256 ];
public:
//--------------------------------------------------------------------------
// 构造函数 , 生成根节点
//--------------------------------------------------------------------------
T_LIST10()
{
m_pcursor= NULL;
m_proot = new T_NODE10 ;
m_lcount = 0 ;
m_lnodecount = 0 ;
m_pcerr[ 0 ] = 0 ;
} ;
//--------------------------------------------------------------------------
// 析构函数,清除链表,但保留链表的数据成员
//--------------------------------------------------------------------------
~T_LIST10()
{
if( m_proot )
RemoveAll( 1 );
if( m_proot )
delete m_proot ;
} ;
//--------------------------------------------------------------------------
// 返回异常情况的错误
//--------------------------------------------------------------------------
inline char* ReturnError()
{
return m_pcerr ;
};
//--------------------------------------------------------------------------
// 返回存放的数据总量。
//--------------------------------------------------------------------------
inline long ReturnCount()
{
return m_lcount ;
};
//--------------------------------------------------------------------------
// 返回节点总量。
//--------------------------------------------------------------------------
inline long ReturnNodeCount()
{
return m_lnodecount ;
};
//--------------------------------------------------------------------------
//
// content: 根据索引和值插入节点。以后可以根据这个索引把值取出来
//
// input:
// p_index -> 索引。
// 必须全部是'0' ~ '9'之间的字符构成的字符串。
// 不能为空
// 不能含其他字符
// 该索引必须是唯一性索引
//
// pData -> 要检索的数据。可以是任意类型。
//
// return:
// 正常返回1,索引异常返回-1,已有节点数据返回0
//
// 注意:数据pData传入以后,List并不申请空间,而是直接引用,因此
// 不能在外面删除
//--------------------------------------------------------------------------
inline short Insert( const char* p_index, TYPE* pData )
{
short j = 1 ;
m_pcursor = m_proot ;
T_NODE10 *p_temp= NULL;
char c ;
for( unsigned i = 0 ; i < strlen( p_index ) ; i ++ )
{
c = p_index[ i ] ;
if( c < '0' || c > '9' )
{
strcpy( m_pcerr,"indexerror!" ) ;
return -1 ;
}
if( m_pcursor -> p_pointer[ c-'0' ] == NULL )
{//节点还没建立
p_temp = new T_NODE10 ;
m_lnodecount ++ ;
m_pcursor -> p_pointer[ c-'0' ] = p_temp ;
}
m_pcursor = m_pcursor -> p_pointer[ c-'0' ] ;
} ;
//在尾节点要插入数据
//验证
if( m_pcursor -> p_data == NULL )
{//唯一性索引尾节点应该没有数据
m_pcursor -> p_data = pData ;
m_lcount ++ ;
}
else
{//
strcpy( m_pcerr , "索引不唯一,不能插入" ) ;
j = 0 ;
}
#ifdef MYDEB
ExportAll();
#endif
return j ;
};
//--------------------------------------------------------------------------
// 数据检索。根据完全索引查询数据。
//
// input:
// p_index -> 索引。
// 必须全部是'0' ~ '9'之间的字符构成的字符串。
// 不能为空
// 不能含其他字符
// 该索引必须是唯一性索引
// output:
// pout -> 所存放的数据
// return:
// 异常返回0,
// 正常返回1,pout指向数据
// 索引太长,返回0,
//
//--------------------------------------------------------------------------
//Create by Rose 2002-03-26
inline short AreaLookup( const char* p_index, TYPE*& pout )
{
short j=0;
m_pcursor = m_proot;
char c = 0;
pout = NULL;
//TYPE * p;
for(unsigned i = 0; i < strlen(p_index); i++)
{
c = p_index[i];
if(m_pcursor->p_pointer[c-'0'] != NULL)
{
m_pcursor = m_pcursor->p_pointer[c - '0'];
if(m_pcursor->p_data)
{
j = 1;
pout = m_pcursor->p_data;
}
}
else
{
if(m_pcursor->p_data)
{
pout = m_pcursor->p_data;
j = 1;
}
break;
}
}
return j ;
};
inline short Lookup( const char* p_index, TYPE*& pout )
{
short j = 1 ;
m_pcursor = m_proot ;
char c = '\0' ;
for( unsigned i = 0 ; i < strlen( p_index ) && j == 1 ; i ++ )
{
c = p_index[ i ] ;
if( m_pcursor -> p_pointer[ c - '0' ] != NULL )
{
m_pcursor = m_pcursor -> p_pointer[ c - '0' ] ;
}
else
{//已经到结尾了
j = 0 ;
strcpy( m_pcerr,"节点没有找到!" ) ;
}
} ;
if( j > 0 )
{
if( m_pcursor -> p_data )
pout = m_pcursor -> p_data ;
else
{
pout = NULL ;
strcpy( m_pcerr,"节点值为空!" ) ;
j = -1 ;
}
}
else
pout = NULL ;
return j ;
};
//--------------------------------------------------------------------------
// 数据检索。根据完全索引查询数据。
//
// input:
// p_index -> 索引。
// 必须全部是'0' ~ '9'之间的字符构成的字符串。
// 不能为空
// 不能含其他字符
// 该索引必须是唯一性索引
// output:
// pout -> 所存放的数据
// level -> 有效索引长度
// return:
// 异常返回0,
// 正常返回1,pout指向数据
// 索引太长,没查到尾节点,返回2,pout指向尾节点的数据
// 索引太长,查到尾节点,返回3,pout指向尾节点的数据
//
//--------------------------------------------------------------------------
inline short Lookup( const char* p_index, TYPE*& pout, int& level )
{
short j = 1 ;
m_pcursor = m_proot ;
char c = '\0' ;
for( level = 0 ; level < (int)strlen( p_index ) && j == 1 ; level ++ )
{
c = p_index[ level ] ;
if( m_pcursor -> p_pointer[ c - '0' ] != NULL )
{
m_pcursor = m_pcursor -> p_pointer[ c - '0' ] ;
}
else
{//已经到结尾了
if( IsTail( m_pcursor ) )
j = 3 ;
else
j = 2 ;
strcpy( m_pcerr,"节点没有找到!" ) ;
break ;
}
} ;
//level -- ;
if( j > 0 )
{
if( m_pcursor -> p_data )
pout = m_pcursor -> p_data ;
else
{
pout = NULL ;
strcpy( m_pcerr,"节点值为空!" ) ;
j = -1 ;
}
}
else
pout = NULL ;
return j ;
};
//--------------------------------------------------------------------------
// 删除全部节点 。
// 参数:
// flag = 0 : 删除全部节点,并且删除节点值
// flag = 1 : 删除全部节点,并且保留节点值不删除
//--------------------------------------------------------------------------
inline void RemoveAll( short flag = 0 )
{
for( short i = 0 ; i < 10 ; i ++ )
{
if( m_proot -> p_pointer[ i ] )
Remove( flag , m_proot -> p_pointer[ i ] ) ;
// Remove( flag , m_proot , m_proot -> p_pointer[ i ] ) ;
}
m_lcount = 0 ;
};
//--------------------------------------------------------------------------
// 信息输出。把索引和存储信息输出到文件中。
// 注意:存储的数据如果是类,一般无法输出类信息。
//--------------------------------------------------------------------------
inline void ExportAll( char* pctext = "my_log_.txt" )
{//遍历
FILE *p_file = fopen( pctext,"a+" ) ;
if( p_file )
{
fprintf( p_file,"\r\n\r\n\r\n================== Begin " ) ;
char pc_ind[ 20 ] = "";
for( short i = 0 ; i < 10 ; i ++ )
{
pc_ind[ 0 ] = i + '0' ;
pc_ind[ 1 ] = NULL ;
if( m_proot -> p_pointer[ i ] )
Export( pc_ind , m_proot -> p_pointer[ i ] ,p_file );
}
fprintf( p_file,"\r\n================== End " ) ;
}
if( p_file )
fclose( p_file ) ;
};
protected:
//--------------------------------------------------------------------------
// 删除父节点 p_father下的子节点p_node,以及该节点下的所有节点。
// 一般不在外面调用.
// flag = 0 : 删除全部节点,并且删除节点值
// flag = 1 : 删除全部节点,并且保留节点值不删除
//--------------------------------------------------------------------------
inline void Remove( short flag, T_NODE10*& p_node )
{//递归删除,
// if( p_node == NULL )
// return ;
for( short i = 0 ; i < 10 ; i ++ )
{
if( p_node -> p_pointer[ i ] )
Remove( flag , p_node -> p_pointer[ i ] );
}
//删除当前节点
if( flag == 0 )
{
if( p_node -> p_data )
delete p_node -> p_data ;//删除节点值
}
delete p_node ;
p_node = NULL ;
} ;
/*
inline void Remove( short flag, T_NODE10* p_father,T_NODE10* p_node )
{//递归删除,
// if( p_node == NULL )
// return ;
if( !IsTail( p_node ) )
{//不是尾
for( short i = 0 ; i < 10 ; i ++ )
{
if( p_node -> p_pointer[ i ] )
Remove( flag , p_node , p_node -> p_pointer[ i ] );
}
};
//把父节点置空
for( short j= 0, i = 0 ; i < 10 && j == 0 ; i ++ )
{
if( p_father -> p_pointer[ i ] == p_node )
{
p_father -> p_pointer[ i ] = NULL ;
j = 1 ;
}
}
//删除当前节点
if( flag == 0 )
{
if( p_node -> p_data )
delete p_node -> p_data ;//删除节点值
}
delete p_node ;
} ;
*/
//--------------------------------------------------------------------------
// 某一节点开始的信息输出。把索引和存储信息输出到文件中。
// 注意:存储的数据如果是类,一般无法输出类信息。
//--------------------------------------------------------------------------
inline void Export( char* pc_ind, T_NODE10* pnode, FILE * p_file )
{
char pctemp[ 20 ];
strcpy( pctemp, pc_ind );
fprintf( p_file,"\r\n----%s ", pctemp ) ;
if( pnode -> p_data != NULL )
{
// fprintf( p_file," %s ", pnode -> p_data -> Output() ) ;
// fprintf( p_file," %s DATA" ) ;
}
if( !IsTail( pnode ) )
{//不是尾节点
for( short i = 0 ; i < 10 ; i ++ )
{
char str[2]="0" ;
if( pnode -> p_pointer[ i ] )
{
//update index
str[ 0 ] += i ;
strcat( pctemp,str ) ;
if( pnode -> p_pointer[ i ] )
Export( pctemp, pnode -> p_pointer[ i ], p_file );
}
}
}
else
{
if( pnode -> p_data == NULL )
{
fprintf( p_file,"\r\n----%s -- %error:tail null!",pctemp ) ;
}
}
} ;
//--------------------------------------------------------------------------
// 判断本节点是否是尾节点。
//--------------------------------------------------------------------------
inline short IsTail( T_NODE10* pnode )
{
for( short i = 0 ; i < 10 ; i ++ )
{
if( pnode->p_pointer[ i ] )
return 0 ;
}
return 1 ;
} ;
};
#endif
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -