C++结合泛型编程简单实现通用链表

前言:

由于数据结构掌握的不太扎实,最近重新学习了一遍数据结构,因为我发现大部分数据结构的教学内容用的都是伪代码或者纯C语言,而C++的一大优点泛型编程却没怎么被提起,所以打算从头开始用泛型编程简单的去实现所有的数据结构类型。


正文:

以下是一个简单的C++泛型编程实现的链表,仅供参考。


myList.hpp

C++泛型编程的头文件是.hpp格式,具体要想了解的可以百度,这里不做多余赘述

#include<iostream>
//C++ 模板链表的实现,带头结点
using namespace std;

template<class T>
class LNode {
public:
	T data;
	LNode* next;
};
template<class T>
class Link {
private:
	LNode<T>* frist;
	int sz;
public:
	Link();
	Link(int sz);
	~Link();


	//展示数据
	void show();
	T& operator[](int pos);
	//插入与删除
	void insert(int pos,const T &elem);
	void erase(int pos);
	//清空
	void clear();
	//判断是否为空
	bool isEmpty();
	//获取数据元素个数
	int size();
	//查找下标(第一次出现)
	int find(const T &elem);
	//查找下标(指定起始位置)
	int find(int beg,const T &elem);
	//查找出现次数
	int count(const T &elem);
};

template<class T>
inline Link<T>::Link()
{
	this->frist = new LNode<T>;
	this->sz = 0;
	this->frist->next = NULL;
}

template<class T>
inline Link<T>::Link(int sz)
{
    //尾插法数据由用户输入
	this->frist = new LNode<T>;
	this->frist->next = NULL;
	this->sz = sz;
	LNode<T>* pend = this->frist;//尾结点
	int i = 0;
	while (i < sz)
	{
		LNode<T>* pnew = new LNode<T>;
		pnew->next = NULL;
		cout << "请输入: ";
		cin >> pnew->data;
		cout << endl;
		pend->next = pnew;
		pend = pnew;//尾结点等于新节点
		i++;
	}
}

template<class T>
inline Link<T>::~Link()
{
	if (this->sz == 0)
	{
		delete this->frist;
		return ;
	}
	LNode<T>* p = this->frist->next;//找到头结点指向的下一个结点
	while (p != NULL)
	{
		LNode<T>* del = p;
		p = p->next;
        //测试是否数据被正常析构
		//cout << "数据: " << del->data << "已释放" << endl;
		delete del;
	}
	delete this->frist;//最后释放头结点
}





template<class T>
inline void Link<T>::show()
{
	if (this->sz == 0)
	{
		cout << "[ ]" << endl;
		return;
	}
	cout << "[ ";
	LNode<T>* p = this->frist->next;
	while (p != NULL)
	{
		cout << p->data << " ";
		p = p->next;
	}
	cout << "]" << endl;
}
template<class T>
T& Link<T>::operator[](int pos)
{
	if (pos > this->sz - 1 || pos < 0)
	{
		cout << "坐标有误" << endl;
		T err = 0;
		return err;
	}
	LNode<T>* p = this->frist;
	for (int i = 0; i <= pos; i++)
	{
		p = p->next;
	}
	return p->data;
}

template<class T>
inline void Link<T>::insert(int pos, const T& elem)
{
	if (pos > this->sz || pos < 0)
	{
		cout << "error: the pos is error" << endl;
		return ;
	}
	LNode<T>* p = this->frist;
	for (int i=0;i<=pos-1;i++)
	{
		p = p->next;
	}
	LNode<T>* pnew = new LNode<T>;
	pnew->data = elem;
	pnew->next = p->next;
	p->next = pnew;
	this->sz++;
	return ;
}

template<class T>
inline void Link<T>::erase(int pos)
{
	if (pos < 0 || pos >= this->sz)
	{
		cout << "the pos is error" << endl;
		return;
	}
	LNode<T>* p = this->frist;
	for (int i=0;i<pos;i++)
	{
		p = p->next;
	}
	//当心内存泄漏!!!
	LNode<T>* del = p->next;
	p->next = p->next->next;
	delete del;
	this->sz--;
}

template<class T>
inline void Link<T>::clear()
{
	if (this->frist->next == NULL)
	{
		return;
	}
	LNode<T>* p = this->frist->next;
	while (p != NULL)
	{
		LNode<T> *del = p;
		p = p->next;
		delete del;
	}
	this->frist->next = NULL;
	this->sz = 0;
}

template<class T>
inline bool Link<T>::isEmpty()
{
	if (this->frist->next == NULL && this->sz == 0)
		return true;
	return false;
}

template<class T>
inline int Link<T>::size()
{
	return this->sz;
}

template<class T>
inline int Link<T>::find(const T& elem)
{
	LNode<T>* p = this->frist->next;
	int i = 0;
	while (p != NULL && p->data!=elem)
	{
		p = p->next;
		i++;
	}
	if (p == NULL)
	{
		return -1;
	}
	return i;
}

template<class T>
inline int Link<T>::find(int beg, const T& elem)
{
	if (beg<0 || beg>this->sz - 1)
	{
		cout << "起始坐标有误" << endl;
		return -1;
	}
	LNode<T>* p = this->frist->next;
	int i = 0;
	while ( i<=beg )
	{
		p = p->next;
		i++;
	}
	//从前驱开始查找
	while (p != NULL && p->data != elem)
	{
		p = p->next;
		i++;
	}

	if (p != NULL) return i;

	else return -1;
}

template<class T>
inline int Link<T>::count(const T& elem)
{
	int count=0;
	LNode<T>* p = this->frist->next;
	while (p!=NULL)
	{
		if (p->data == elem)
		{
			count++;
		}
		p = p->next;
	}
	return count;
}

test.cpp

测试代码:

#pragma once
#include<iostream>
#include"myList.hpp"
using namespace std;
void test01()
{
	Link<int> lnk(5);
	lnk.show();
	int a = lnk.find(1);
	while (a != -1)
	{
		cout << "找到: " <<"下标:"<<a<<" "<< lnk[a] << endl;
		a = lnk.find(a,1);
	}
	int b = lnk.count(1);
	cout << "共出现:" << b << "次" << endl;

}

int main()
{
	test01();
	return 0;
}

注意:

测试代码只提供了一部分测试数据,想要测试自定义类型需要额外重载几个运算符,这只是一个向C++模板编程靠拢的demo版本。 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值