1.模板文件 t_list_unidir
#include <iostream>
#ifndef NULL
#define NULL ((void*)0)
#endif
//链表节点模板类
template <typename T>
class list_unidir
{
public:
T m_data;
list_unidir * p_next;
};
/*****************************************************************
*函数名:
*list_unidir<T> *list_unidir_create(const list_unidir<T> *)
*功能:
*创建一个单向链表
*参数:
*指定类型的指针
*返回值:
*链表头的指针
*说明:
*无
*****************************************************************/
template <typename T>
list_unidir<T> * list_unidir_create(const list_unidir<T> *)
{
list_unidir<T> * p_head = new list_unidir<T> ;
if(!p_head)
return NULL;
p_head->p_next = NULL;
return p_head;
}
/*****************************************************************
*函数名:
*void list_unidir_destroy(list_unidir<T> *p_head)
*功能:
*销毁一个单向链表
*参数:
*链表头的指针
*返回值:
*空
*说明:
*删除链表,释放内存空间
*****************************************************************/
template <typename T>
void list_unidir_destroy(list_unidir<T> *p_head)
{
list_unidir<T> * p_node ;
while(p_head)
{
p_node = p_head ->p_next;
delete p_head ;
p_head = p_node ;
}
}
/*****************************************************************
*函数名:
*bool list_unidir_push(
* list_unidir<T> *p_head, const T &node_value)
*功能:
*向单向链表中压入数据
*参数:
*p_head~链表头的指针 ; node_value~节点值变量的引用
*返回值:
*bool值指示操作是否成功
*说明:
*无
*****************************************************************/
template <typename T>
bool list_unidir_push(
list_unidir<T> *p_head, const T & node_value)
{
list_unidir<T> * p_node ;
if(!p_head )
return false;
p_node = new list_unidir<T> ;
if(!p_node)
return false ;
p_node ->m_data = node_value ;
p_node ->p_next = p_head ->p_next;
p_head ->p_next = p_node;
return true ;
}
/*****************************************************************
*函数名:
*bool list_unidir_del_node(
* const list_unidir<T> *p_head, list_unidir<T> *p_node)
*功能:
*从单向链表中删除数据节点
*参数:
*p_head~链表头的指针 ; p_node~指定待删节点的指针
*返回值:
*bool值指示操作是否成功
*说明:
*无
*****************************************************************/
template <typename T>
bool list_unidir_del_node(
list_unidir<T> *p_head, list_unidir<T> *p_node)
{
list_unidir<T> *p_prev = p_head ;
if(!p_head)
return false;
while(p_prev && p_prev->p_next != p_node)
p_prev = p_prev -> p_next ;
//Not found ,return NULL
if(!p_prev)
return false;
p_prev ->p_next = p_node ->p_next ;
delete p_node ;
p_node = NULL ;
return true ;
}
/*****************************************************************
*函数名:
*list_unidir<T> * list_unidir_find_node(
* const list_unidir<T> *p_head,const T & node_value)
*功能:
*从单向链表中删除数据节点
*参数:
*p_head~链表头的指针 ; node_value~待比较节点值
*返回值:
*指向查找到的节点的指针
*说明:
*如果操作失败,那么返回一个无效指针NULL
*****************************************************************/
template <typename T>
list_unidir<T> * list_unidir_find_node(
const list_unidir<T> *p_head,const T & node_value)
{
list_unidir<T> *p_node = p_head ->p_next;
while(p_node)
if((p_node ->m_data) == node_value)
return p_node ;
else
p_node = p_node -> p_next ;
return NULL ;
}
/*****************************************************************
*函数名:
*bool list_unidir_copy_node(
* const list_unidir<T> *p_node,T * value_addr)
*功能:
*从单向链表中拷贝数据节点到外部
*参数:
*p_node~指定待拷贝节点的指针 ; value_addr~用来接收数据的变量地址
*返回值:
*bool值指示操作是否成功
*说明:
*无
*****************************************************************/
template <typename T>
bool list_unidir_copy_node(
const list_unidir<T> *p_node,T * value_addr)
{
if(!p_node || !value_addr)
return false;
*value_addr = p_node ->m_data ;
return true ;
}
/*****************************************************************
*函数名:
*bool list_unidir_pop(
* list_unidir<T> *p_head,T * value_addr)
*功能:
*从单向链表中弹出数据
*参数:
*p_head~链表头指针 ; value_addr~用来接收数据的变量地址
*返回值:
*bool值指示操作是否成功
*说明:
*无
*****************************************************************/
template <typename T>
bool list_unidir_pop(
list_unidir<T> *p_head,T * value_addr)
{
list_unidir<T> *p_node ;
if(!p_head ||!p_head->p_next||!value_addr)
return false;
p_node = p_head ->p_next ;
*value_addr = p_node ->m_data ;
p_head->p_next = p_node ->p_next ;
delete p_node ;
p_node = NULL;
return true ;
}
/*****************************************************************
*函数名:
*void list_unidir_traverse(
* const list_unidir<T> *p_head)
*功能:
*遍历链表/输出每个节点
*参数:
*p_head~链表头指针
*返回值:
*无
*说明:
*如果要调用此方法,必须保证类型T支持输出重定向操作符 <<
*****************************************************************/
template <typename T>
void list_unidir_traverse(
const list_unidir<T> *p_head)
{
while(p_head = p_head ->p_next)
{
std::cout <<p_head<<std::endl;
}
}
2.测试文件 test.cpp
#include <iostream>
#include <string>
#include "t_list_unidir"
using namespace std;
//一个简单的 用于测试模板链表的类
class CA
{
private:
string m_str;
public:
CA(const string &s):m_str(s){}
CA(){m_str = "";}
void set_string(const string &s){m_str=s;}
string get_string()const {return m_str;}
//拷贝节点所必需支持的重载函数
CA & operator=(const CA &k)
{
m_str = k.m_str;
}
};
//遍历链表所必需支持的重载函数
ostream & operator<<(ostream &os,const CA &s)
{
os << s.get_string() ;
}
//查找节点所必需支持的重载函数
bool operator==(const CA &k,const CA &s)
{
string k1 = k.get_string();
string s1 = s.get_string();
return k1==s1 ;
}
int main()
{
const string c_s[4]={
"Hello world!",
"This is a sentence.",
"Oh my God!",
"Really ?"
};
list_unidir<CA> *l_ca;
l_ca = list_unidir_create(l_ca);
for(int k = 0;k<4;k++)
{
list_unidir_push(l_ca,CA(c_s[k]));
cout << "PUSH:"<<c_s[k]<<endl;
}
string *ps,s("This is a sentence.");
list_unidir<CA> *p_node ;
p_node = list_unidir_find_node(l_ca,CA(s));
if(p_node)
cout <<"FIND:"<<(p_node ->m_data).get_string()<<endl
<<"with:"<<s<<endl;
if(p_node)
{
CA *p_tmp = new CA ;
if(!list_unidir_copy_node(p_node,p_tmp))
cerr << "Find Ok,but copy error!"<<endl;
else
{
cout << p_tmp->get_string()<<endl;
p_tmp->set_string("hello world!");
cout << p_tmp->get_string()<<endl;
cout <<"Copy out class from list OK!"<<endl;
}
delete p_tmp;
}
list_unidir_traverse(l_ca);
if(p_node)
{
cout << "Now ,trying to delete node :"<<(p_node->m_data).get_string()<<endl;
if(!list_unidir_del_node(l_ca,p_node))
cerr << "Delete Node Failure !"<<endl;
}
list_unidir_traverse(l_ca);
CA* p_t=new CA;
do
{
if(!list_unidir_pop(l_ca,p_t))
break;
else
cout <<"POP :"<<p_t->get_string()<<endl;
}
while(true);
list_unidir_destroy(l_ca);
return 0;
}