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

来源:互联网 发布:招财猫是什么软件 编辑:程序博客网 时间:2024/06/05 11:50

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

首先介绍模板函数:顾名思义,就是一个模板让别的事物套用的,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为非基本类型时不能用memcpyfor (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;}

运行函数,查看结果:

wKioL1bpdJnivOJUAAAfHbNXXmU368.png

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


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

本文出自 “分享中进步” 博客,请务必保留此出处http://xmwen1.blog.51cto.com/10730069/1751962

0 0
原创粉丝点击