小明哥教你使用模板函数实现顺序表

阅读本文需要对顺序表有一定的了解,欢迎您的阅读。

首先介绍模板函数:顾名思义,就是一个模板让别的事物套用的,c++中的模板就是同一结构的不同类型套用的,举个简单例子,要使用这个结构的模板,int可以用,char也可以用,等等


好了不罗嗦了,直接上实现函数吧!

模板结构如下:

template<typename T> //模板函数,T为参数类型
class SeqList
{
public:
	SeqList();
	SeqList(T *array, size_t size);
	SeqList(const SeqList &s); //现代写法
	SeqList &operator=(SeqList s);
	~SeqList();
	void PushBack(const T& x);   //尾增
	void PopBack();    //尾删
	void PushFount(const T& x);  //头增
	void PopFount();  //头删
	void Insert(size_t pos, const T& x);  //中间插入
	void Erase(size_t pos);  //中间删除
	int Find(T x);   //寻找
	void PrintSeqList();  //输出
	void _CheekCapacity();  //检查容量

private:
	T *_array;
	size_t _size;
	size_t _capaci;
};

构造函数、赋值运算符重载函数:

template<typename T>
SeqList<T>::SeqList()
:_array(NULL),
_size(0),
_capaci(0)
{}

template<typename T>
SeqList<T>::SeqList(T *array, size_t size)
: _array(new T[size]),
_size(size),
_capaci(size)
{
	//memcpy(_array, array, sizeof(T)*size);  //当T为非基本类型时不能用memcpy
	for (size_t i = 0; i < size; i++)
	{
		_array[i] = array[i];
	}
}

//template<typename T>
//SeqList<T>::SeqList(const SeqList& s)  //传统写法
//	:_array(new T[s._size]),
//	_size(s._size),
//	_capaci(s._size)
//{
//	//memcpy(_array, s._array, sizeof(T)*_size);
//	for (size_t i = 0; i < size; i++)
//	{
//		_array[i] = array[i];
//	}
//}

template<typename T>
SeqList<T>::SeqList(const SeqList &s) //现代写法
:_array(NULL)
{
	SeqList temp(s._array, s._size);
	swap(_array, temp._array);
	_size = s._size;
	_capaci = s._capaci;
}

template<typename T>
SeqList<T>& SeqList<T>::operator=(SeqList s)
{
	swap(s._array, _array);
	_size = s._size;
	_capaci = s._capaci;
	//swap(_size,s._size);
	//swap(_capaci,s._capaci);
	return *this;
}

//template<typename T>
//SeqList<T>& SeqList<T>::operator=(const SeqList s)
//{
//	if (this != &s)
//	{
//		T *temp = new T[s._size];
//		delete[]_array;
//		_array = temp;
//		_size = s._size;
//		_capaci = s._size;
//		for (size_t i = 0; i < _size; i++)
//			temp[i] = _array[i];
//	}
//	return *this;
//}

析构函数:

template<typename T>
SeqList<T>::~SeqList()
{
	if (_array)
	{
		delete[] _array;
	}
}

插入删除函数:

template<typename T>
void SeqList<T>::PushBack(const T& x)
{
	_CheekCapacity();
	_array[_size] = x;
	_size++;
}

template<typename T>
void SeqList<T>::PopBack()
{
	if (_size > 0)
	{
		_size--;
	}
}

template<typename T>
void SeqList<T>::PushFount(const T& x)
{
	_CheekCapacity();
	for (int i = _size; i > 0; i--)
	{
		_array[i] = _array[i - 1];
	}
	_array[0] = x;
	_size++;
}

template<typename T>
void SeqList<T>::PopFount()
{
	if (_size == 0)
	{
		cout << "空链表" << endl;
	}
	for (size_t i = 0; i < _size - 1; i++)
	{
		_array[i] = _array[i + 1];
	}
	_size--;
}

template<typename T>
void SeqList<T>::Insert(size_t pos, const T& x)
{
	_CheekCapacity();
	if (pos<_size)
	for (int i = _size; i > _size - pos; i--)
	{
		_array[i] = _array[i - 1];
	}
	_array[pos - 1] = x;
	_size++;
}

template<typename T>
void SeqList<T>::Erase(size_t pos)
{
	if (_size == 0)
	{
		cout << "空链表,无需删除!" << endl;
	}
	for (int i = pos; i < _size; i++)
	{
		_array[i - 1] = _array[i];
	}
	_size--;
}

寻找值的函数、输出内容函数:

template<typename T>
int SeqList<T>::Find(T x)
{
	if (_size == 0)
	{
		cout << "空链表!" << endl;
	}
	for (int i = 0; i < _size; i++)
	{
		if (x == _array[i])
		{
			return i + 1;
		}
	}
	return -1;
}

template<typename T>
void SeqList<T>::PrintSeqList()
{
	for (int i = 0; i < (int)_size; i++)
		cout << _array[i] << "  ";
	cout << endl;
}

检查容量和增容函数:

template<typename T>
void SeqList<T>::_CheekCapacity()
{
	if (_size >= _capaci)
	{
		_capaci = 2 * _capaci + 3;
	    T* temp = new T[_capaci];
		for (size_t i = 0; i < _size; i++)
			temp[i] = _array[i];
		swap(_array, temp);
	}
}

上述代码全部定义于我自定义的typetemp.h头文件中,并写在#ifndef _TYPETEMP_H__  #define _TYPETEMP_H__  和  #endif之间


测试函数如下:

#include"SeqList.h"

void test2()
{
	cout << "使用 int 类型构造 :" << endl;
	cout << "s1:" << endl;
	SeqList<int> s1;
	s1.PushBack(1);
	s1.PushBack(2);
	s1.PushBack(3);
	s1.PushBack(4);
	s1.PushBack(5);
	s1.PrintSeqList();
	cout << "s2:" << endl;
	SeqList<int> s2(s1);
	s2.PopBack();
	s2.PrintSeqList();

	cout << "s3:" << endl;
	SeqList<int> s3;
	s3 = s1;
	s3.PopFount();
	s3.PrintSeqList();
}

void test3()
{
	cout << "使用 char 类型构造 :" << endl;
	cout << "s1:" << endl;
	SeqList<char> s1;
	s1.PushBack('a');
	s1.PushBack('b');
	s1.PushBack('c');
	s1.PushBack('d');
	s1.PushBack('e');
	s1.PrintSeqList();
	cout << "s2:" << endl;
	SeqList<char> s2(s1);
	s2.PopBack();
	s2.PrintSeqList();

	cout << "s3:" << endl;
	SeqList<char> s3;
	s3 = s1;
	s3.PopFount();
	s3.PrintSeqList();
}

void test4()
{
	cout << "使用 string 类型构造 :" << endl;
	cout << "s1:" << endl;
	SeqList<string> s1;
	s1.PushBack("xxxx");
	s1.PushBack("ssss");
	s1.PushBack("aaaa");
	s1.PushBack("dddd");
	s1.PushBack("eeee");
	s1.PrintSeqList();
	cout << "s2:" << endl;
	SeqList<string> s2(s1);
	s2.PopBack();
	s2.PrintSeqList();

	cout << "s3:" << endl;
	SeqList<string> s3;
	s3 = s1;
	s3.PopFount();
	s3.PrintSeqList();
}

int main()
{
	test2();
	test3();
	test4();

	system("pause");
	return 0;
}

运行函数,查看结果:

小明哥教你使用模板函数实现顺序表_第1张图片

注意事项:当使用基本类型,如int char float 等类型时,模板函数可以用memcpy,realloc 等涉及内存的函数;当时用非基本类型,如string 类型时,模板函数不能使用memcpy等涉及内存操作的函数,因为会产生程序崩溃等现象,原因是由于调用析构函数引起的,这里就不详加讨论,这篇文章里的函数都没有使用memcpy 等函数,这样函数还不是最优化的,优化方案我会在下一篇博客 <模板函数-类型萃取>里边解决,欢迎阅读,谢谢!


限于我目前的c++水平 仅能实现上述函数,欢迎大家阅读,如发现错误或者不足,恳请您给予批评指正,谢谢!

你可能感兴趣的:(模板函数,基本类型)