C++模板实现单向链表

模板实现头文件:

#ifndef	SUN_LINKLIST_H
#define  SUN_LINKLIST_H
#include <iostream>
using namespace std ;
//#include "List.h"
// T : operator= , operator!= , operator== , copy constructor , assign constructor
#define SUN_LINKLIST_DEBUG
#ifdef	SUN_LINKLIST_DEBUG						//pause
#define	PAUSE (system("pause"))
#else
#define	PAUSE (0)
#endif

template<typename T> class LinkList ;
template<typename T> class LinkNode ;
template <typename T> ostream& operator<<(ostream & _cout , const LinkNode<T>& _linknode ) ; 

template < typename T > class LinkNode //LinkNode type
{
public:
	LinkNode( ) ;
	LinkNode( const T & _value ) ;
	LinkNode( const LinkNode<T>& _linknode ) ; 

	virtual ~LinkNode() ;
	LinkNode<T>& operator= (const LinkNode<T> & _right) ;
	friend ostream& operator<< <T>(ostream & _cout , const LinkNode<T> &linknode) ;
	friend class LinkList<T> ; 

private:
	T data ; LinkNode<T> * pnext ;
} ;
template<typename T> LinkNode<T> ::LinkNode( ) :data( )												//!!!default constructor
{
	pnext = NULL ;
}
template<typename T> LinkNode<T>::LinkNode(const T & _value)
{
		data = _value ;
		pnext = NULL ;
}
template <typename T> LinkNode<T> ::LinkNode(const  LinkNode<T> &_linknode )
{
	data = _linknode .data ;																											//!!!!operator ==
	pnext = NULL ;
}
template <typename T>  LinkNode< T > ::~LinkNode(){ } ;

template <typename T> ostream & operator<< (ostream & _cout , const LinkNode<T>& _linknode )
{
	_cout<<"link node data : "<<_linknode .data ;															//!!!!T operator <<
	return _cout ;
}
template <typename T>  LinkNode<T> & LinkNode< T > ::operator=(const LinkNode< T > &_right)
{
	data = _right .data ;
	pnext = _right .pnext ;
	return *this ;
}

template< typename T > class LinkList
{

private:
	LinkNode<T>  *linkhead ;
	size_t				linklength ;

	LinkNode <T> *find_ins_pos(size_t _ins_pos ) ;
	int copydata( const LinkList<T>  & _ls ,  size_t _start , size_t _end ) ;

public:
	LinkList( );
	LinkList( const LinkList<T> & _linklist ) ;
	LinkList<T> & operator= ( const LinkList<T> & _linklist ) ;
	~LinkList() ; 

	int insert(size_t _ins_pos , const T & _value) ;
	int remove(size_t _ins_pos ,  T & _value ) ;
	int find (const T & _value) const ;
	int replace(size_t _re_pos ,  const T & _value);
	T & get(size_t _pos ) const ; 

	bool isempty( ) { return linklength == 0 } ;
	int	get_link_length( ) const { return linklength ; } ;
};

template <typename T> LinkList<T>::LinkList( )
{
	linkhead = NULL ;
	linklength = 0 ;
}
template <typename T> LinkList<T> ::LinkList(const LinkList<T> & _ls)
{
	linkhead = NULL ;
	linklength = 0 ;
	copydata(_ls , 0 , _ls .get_link_length( ) ) ;

}
template <typename T> T &LinkList<T> ::get(size_t _pos ) const
{
	LinkNode<T> *pln_temp = linkhead ; 

	size_t i = 0 ;
	while(pln_temp != NULL &&  i < _pos )
	{
		pln_temp = pln_temp ->pnext ; i++ ;
	}

	if(pln_temp == NULL )
	{
		cout<<"get : _pos range ERROR"<<endl ;
		PAUSE;
	}

	return pln_temp ->data ;										//operator=

}
template< typename T> int LinkList < T > ::insert(size_t _ins_pos , const T & _value)
{

	LinkNode< T > *pln = NULL ;
	if(_ins_pos == 0 )						//insert to the first place of the link list
	{
		pln = new LinkNode< T >( _value ) ;
		pln ->pnext = linkhead ;
		linkhead = pln  ;
		linklength++ ;
		return 0 ;
	}

	pln = linkhead ;
	size_t i = 0 ;
	while( pln != NULL && ( i < (_ins_pos - 1 ) ) ) { pln = pln ->pnext ; i++ ; }

	if( pln == NULL)			//insert range  ERROR
	{
		cout<< "the range of the inset position is ERROR"<<endl ;
		return  -1 ;
	}

	LinkNode<T> *pln_temp = new LinkNode<T>(_value) ;
	pln_temp ->pnext = pln ->pnext ;
	pln ->pnext = pln_temp ;
	linklength++ ;
	return 0 ;
}
template <typename T> int LinkList < T > ::copydata(const LinkList< T > &_ls , size_t _start , size_t _end )
{
	linkhead = NULL ;  linklength = 0 ; 

	LinkNode< T > *pln = _ls .linkhead ;
	LinkNode< T > *phead = NULL;  

	if(_ls .linklength == 0 ) { return 0 ; }						// link list empty return
	linkhead = new LinkNode<T>( *(_ls .linkhead ) ) ;  // not empty
	pln = pln ->pnext ; phead = linkhead ;
	linklength++ ; 

	while (pln != NULL )
	{
		phead ->pnext = new LinkNode<T> ( *( pln ) ) ;
		phead  = phead ->pnext ;
		pln  = pln ->pnext ;
		linklength++ ;
	}

	phead ->pnext = NULL ;										//the pnext of the link end is NULL
	return 0 ;
}
template <typename T> int LinkList<T> ::remove(size_t _rm_pos ,  T & _value )
{
	if( linkhead == NULL ||  _rm_pos < 0 || ( linklength - 1 < _rm_pos ) )
	{
		cout<<"remove : _rm_pos range error"<<endl ;
		return -1;
	}

	LinkNode<T> *pln_temp = linkhead ;
	if(_rm_pos == 0 )
	{
		_value = pln_temp ->data ;    // !!!!! T operator=
		linkhead = linkhead ->pnext ;
		delete pln_temp ;
		linklength-- ;
		return  0 ;
	}

	size_t i = 0 ;
	pln_temp = linkhead ;
	while(pln_temp != NULL  && ( i < (_rm_pos - 1) ) ) { pln_temp = pln_temp ->pnext ; i++ ; }

	LinkNode<T> *pln_temp1 = pln_temp ->pnext ;
	pln_temp ->pnext = pln_temp1 ->pnext ;
	_value = pln_temp1 ->data ;
	delete pln_temp1 ;
	linklength-- ;
	return 0 ;

}
template <typename T> int LinkList<T> ::find(const T & value ) const
{
	int i = 0 ;
	LinkNode<T> *pln = linkhead ;
	while(pln != NULL && pln->data != value )     //!!!!!operator!=() of T
	{
		pln = pln ->pnext ; i++ ;
	}

	 if( pln!=NULL )
		return i ;
	 else
		 return -1;
}
template <typename T> int LinkList<T> ::replace(size_t _re_pos , const T & _value)
{
	T a_temp ;
	if(remove(_re_pos , a_temp) != 0 || insert(_re_pos , _value ) != 0 )
	{
		cout<<"replace ERROR"<<endl ;
		return -1;
	}

	return 0 ;
}
template <typename T > LinkList< T > ::~LinkList()
{
	cout<<"de_constructor"<<endl ;

	LinkNode<T> *pln = linkhead ;
	while( linkhead !=NULL)
	{
		cout<<linkhead->data <<endl ;
		pln = linkhead ;
		linkhead = linkhead ->pnext ;
		delete pln ;
	}
} 

#endif

 测试代码:

#include <iostream>
using namespace std ;
#include "LinkList.h"

int main(int argc , char ** argv)
{
		//测试友员类的访问权限
		//LinkList< int > linktest ;
		//int a = 10 ;
		//linktest.funtest(a) ; 

		//测试在linknode 中的重载"<<"操作符"函数
		LinkNode<int> linknode(20) ;
		cout<<linknode<<endl ; 

		//测试LinkNode 的赋值操作符
		LinkNode< int > linknode1 ;
		linknode1 = linknode ;
		cout<<linknode1<<endl ; 

		//测试insert , get 函数
		LinkList<int> ls ;
		for(int i = 0 ; i <100  ; i++ ) { ls .insert(0 , i ) ; }

		for(int i = 0 ; i < ls .get_link_length( ) ; i++ )
		{
			cout<<ls .get(i)<<endl ;
		}

		//测试copy constructor
		cout<<"copy constructor"<<endl ;
		LinkList<int> ls2(ls) ;
		for(int i = 0 ; i < ls2.get_link_length() ; i++ )
		{
			cout<<ls2 .get( i )<<endl ;
		}

		//测试remove函数
		cout<<"test remove"<<endl ;
		int i ;
		ls2 .remove(0 , i) ;
		cout<<"i = "<<i<<endl ;
		for(int i = 0 ; i < ls2.get_link_length() ; i++ )
		{
			cout<<ls2 .get( i )<<endl ;
		}

		ls2 .remove(1 , i ) ;
		cout<<"i = "<<i<<endl ;
		for(int i = 0 ; i < ls2.get_link_length() ; i++ )
		{
			cout<<ls2 .get( i )<<endl ;
		}

		//测试find()
		cout<<"test find"<<endl ;
		int i1 = 0 ;
		cout<<ls .find( i1 )<<endl ; 

		//测试replace
		cout<<"replace"<<endl;
		int i2 = -3 ;
		ls .replace(99 , i2) ;
		cout<< ls .get(99)<<endl ; 

		system("pause") ;
		return 0 ;
}

  

C++模板实现单向链表

时间: 2024-10-31 17:38:55

C++模板实现单向链表的相关文章

模板实现单向链表

 /************************************           WZ ASUST   2016         模板实现单向链表 ************************************/ #include"sts.h" template <class T> struct node { public:node(const T &d):next(NULL),data(d){} T data; node<T>

单向链表模板

写个单向链表模板练练手: #include <bits/stdc++.h> using namespace std; //create // delete // modify // search class Node{ public: int data; Node* ptr; Node(int elem= 0, Node* node= NULL){ this->data= elem; this->ptr= NULL; } }; class MyList{ private: Node

数据结构-单向链表 C和C++的实现

数据结构,一堆数据的存放方式. 今天我们学习数据结构中的 链表: 数组,大家相当熟悉的存放数据方式,而链表是数组的一种特殊方式,它每个节点包括两个部分: 数据域:存放数据,此部分与数组相同 指针域:存放了下一个节点的地址 链表比数组多了指针域,因为链表需要通过上一个节点的指针域去找下一个数据,比如有一个链表ABCD四个节点,我们要访问D里边的数据.操作如下: 先通过A节点的指针域找到B节点 再通过B节点的指针域找到C节点 再通过C节点的指针域找到D节点 获取D节点数据域的数据 对比数组直接通过下

C语言实现简单的单向链表(创建、插入、删除)及等效STL实现代码

实现个算法,懒得手写链表,于是用C++的forward_list,没有next()方法感觉很不好使,比如一个对单向链表的最简单功能要求: input: 1 2 5 3 4 output: 1->2->5->3->4 相当于仅仅实现了插入.遍历2个功能(当然遍历功能稍微修改就是销毁链表了) 用纯C写了份测试代码 /* 基本数据结构的定义以及函数的声明 */ typedef int ElemType; typedef struct Node { ElemType elem; struc

【转】Linus:利用二级指针删除单向链表

原文作者:陈皓 原文链接:http://coolshell.cn/articles/8990.html 感谢网友full_of_bull投递此文(注:此文最初发表在这个这里,我对原文后半段修改了许多,并加入了插图) Linus大婶在slashdot上回答一些编程爱好者的提问,其中一个人问他什么样的代码是他所喜好的,大婶表述了自己一些观点之后,举了一个指针的例子,解释了什么才是core low-level coding. 下面是Linus的教学原文及翻译—— “At the opposite en

数据结构与算法学习-单向链表的实现

链表(Chain本文所说链表均为单向链表,以下均简称单向链表)实际上是由节点(Node)组成的,一个链表拥有不定数量的节点.而向外暴露的只有一个头节点(Head),我们对链表的所有操作,都是直接或者间接地通过其头节点来进行的. 节点(Node)是由一个需要储存的对象及对下一个节点的引用组成的.也就是说,节点拥有两个成员:储存的对象.对下一个节点的引用. 这样说可能大家不是很明白,我贴一张图大家可能更容易理解. package LinkedList; /** * <p><strong>

算法总结之 反转部分单向链表

给定单链表的表头节点head, 以及两个整数from 和 to, 在单向链表上把fro个节点到第to个节点这一部分进行反转 思路: 本题 有可能存在换头的问题,所以函数应该返回调整后的新的头节点 1 判断是否满足 1<=from<=to<=N 如果不满足,直接返回原来的头节点 2 找到第from-1个节点pre和第to+1个节点tPos,fPre即要反转部分的前一个节点,tPos是反转部分的后一个节点,把反转部分先反转,然后正确的链接fPre和tPos package TT; impor

C语言之字符单向链表

/* * @Author: suifengtec * @Date:   2017-09-02 16:06:33 * @Last Modified by:   suifengtec * @Last Modified time: 2017-09-02 20:47:13 **/ /* 字符单向链表 gcc -o a.exe main.c && a  */ #include <stdio.h> #include <stdlib.h> #include <stdbool

C++__单向链表(练习)

单向链表 link.h #ifndef LINK_H_ #define LINK_H_ #define HEADER 0 #define TAIL -1 typedef int data_type; enum LINK_OP { LINK_ERR = -1, LINK_OK }; class LINK { private: data_type data; LINK *next; public: LINK(); LINK(data_type data); virtual ~LINK(); data