基于c++模板实现单链表可支持任意数据类型

使用模板实现带头结点的单链表,可以支持任意数据类型。

ps:测试时出现了内存泄漏,检查发现是由于删除节点时没有delete导致的。

LinkList.hpp

#pragma once
#include<iostream>
using namespace std;
template<typename  ElementType>
class LinkNode
{
public:

    LinkNode()
    {

    }

    LinkNode(ElementType value)
    {
        this->next = NULL;
        this->data = value;
    }

    ~LinkNode()
    {
        this->next = NULL;
    }

    LinkNode<ElementType>* next;
    ElementType data;
};

template<typename  ElementType> 
class LinkList
{
public:
    //构造函数
    LinkList();

    //指定位置插入
    void Insert_LinkList(ElementType value, int pos);

    //删除指定位置结点
    void RemoveByPos_LinkList(int pos);

    //删除指定值的结点
    void RemoveByValue_LinkList(ElementType value);

    //查找
    int Find_LinkList(ElementType value);

    //返回链表长度
    int Size_LinkList();

   //返回第一个结点
    ElementType Front_LinkList();

    //打印链表节点
    void Print_LinkList();

    //清空链表
    void Clear_LinkList();

    //析构函数
    ~LinkList();

    LinkNode<ElementType> head;
    int size;
};

template<typename  ElementType>
LinkList<ElementType>:: LinkList()
{
    this->size = 0;
    this->head.next = NULL;
    
}

template<typename  ElementType>
void LinkList<ElementType>::Insert_LinkList(ElementType data , int pos)
{
    if (this == NULL)
    {
        return;
    }

    if (pos< 0 || pos>=this->size)
    {
        pos = this->size;
    }
    
    //创建结点
    LinkNode<ElementType>* pAdd = new LinkNode<ElementType>(data);

    //辅助指针
    LinkNode<ElementType>* pCurrent = &(this->head);
    for (int i = 0; i < pos; i++)
    {
        pCurrent = pCurrent->next;
    }

    pAdd->next = pCurrent->next;
    pCurrent->next = pAdd;
    this->size++;
}

template<typename  ElementType>
void LinkList<ElementType>::RemoveByPos_LinkList(int pos)
{
    if (this == NULL || pos<0 || pos>this->size)
    {
        return;
    }

    //辅助指针
    LinkNode<ElementType>* pCurrent =&(this->head);
    for (int i = 0; i < pos; i++)
    {
        pCurrent = pCurrent->next;
    }

    LinkNode<ElementType>* pDel = pCurrent->next;
    pCurrent->next = pDel->next;
    delete pDel;
    this->size--;
}

template<typename ElementType>
int LinkList<ElementType>:: Find_LinkList(ElementType value)
{
    if (this == NULL)
    {
        return -1;
    }
    
    //辅助指针
    int pos = -1;
    int index = 0;

    LinkNode<ElementType> pAim(value);

    LinkNode<ElementType>* pCurrent = this->head.next;
   
    while (pCurrent != NULL)//用while循环比较好写,for循环考虑比较多
    {
        if (pCurrent->data == pAim.data)
        {
            pos = index;
            break;
        }
        index++;
        pCurrent = pCurrent->next;
    }
     
    return pos;
}

template<typename ElementType>
int LinkList<ElementType>::Size_LinkList()
{
    if (this == NULL)
    {
        return -1;
    }
    
    return this->size;
}

template<typename ElementType>
ElementType LinkList<ElementType>::Front_LinkList()
{ 
   return this->head.next->data;
}

template<typename ElementType>
void LinkList<ElementType>::Print_LinkList()
{
    if (this == NULL)
    {
        return;
    }

        LinkNode<ElementType>* pCurrent = this->head.next;

    while (pCurrent != NULL)
    {
        cout << pCurrent->data <<" ";

        pCurrent = pCurrent->next;
    }
}

template<typename ElementType>
void LinkList<ElementType>::Clear_LinkList()
{
    if (this == NULL)
    {
        return;
    }

    this->size = 0;
}

template<typename ElementType>
LinkList<ElementType>::~LinkList()
{
    if (this == NULL)
    {
        return;
    }

    LinkNode<ElementType>* pCurrent = this->head.next;

    while (pCurrent != NULL)
    {
        LinkNode<ElementType>* pNext = pCurrent->next;
        delete pCurrent;
        pCurrent = pNext;
    }
}

template<typename ElementType>
void LinkList<ElementType>::RemoveByValue_LinkList(ElementType value)
{
    LinkNode<ElementType> pAim(value);

    LinkNode<ElementType>* pCurrent = this->head.next;
    LinkNode<ElementType>* pPrev = &(this->head);

    while (pCurrent != NULL)//用while循环比较好写,for循环考虑比较多
    {
        if (pCurrent->data == pAim.data)
        {
            pPrev->next = pCurrent->next;
            delete pCurrent;
            break;
        }
        
        pPrev = pCurrent;
        pCurrent = pCurrent->next;
    }
     
    this->size--;
}

main.cpp

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

class Person
{
	friend	ostream& operator <<(ostream& cout, Person& p);

public:

	Person()
	{

	}

	Person(string name, int age)
	{
		this->m_Name = name;
		this->m_Age = age;
	}

	bool operator==(const Person& p)
	{
		return this->m_Age == p.m_Age && this->m_Name == p.m_Name;
	}

	string m_Name;
	int m_Age;
};

ostream& operator <<(ostream& cout, Person& p)
{
	cout << "Name: " << p.m_Name << " Age: " << p.m_Age << endl;
	return cout;
}

void test01()
{
	//创建链表
	LinkList<int>* list = new LinkList<int>;

	//插入数据
	for (int i = 0; i < 10; i++)
	{
		list->Insert_LinkList(i, 100);
	}
     
	//打印数据
	list->Print_LinkList();

	//按位置删除
	list->RemoveByPos_LinkList(8);
	cout << endl;

	//按值删除
	list->RemoveByValue_LinkList(4);
	
	//打印数据
	list->Print_LinkList();
	cout << endl;
    
	//按值查找
	int pos = list->Find_LinkList(3);
	cout << "值为3的位置: " << pos << endl;

	//返回链表首节点
	int ret = list->Front_LinkList();
	cout << "首节点: " << ret << endl;
   
    //返回链表长度
	int length = list->Size_LinkList();
	cout << "长度为: " << list->Size_LinkList() << endl;

	//清空链表
	list->Clear_LinkList();
	cout << "清空后长度为: " << list->Size_LinkList()<<endl;

	delete list;
}

void test02()
{
	Person p1("aaa", 10);
	Person p2("bbb", 20);
	Person p3("ccc", 30);
	Person p4("ddd", 40);
	Person p5("eee", 50);

	//创建链表
	LinkList<Person>* list = new LinkList<Person>;
	
	//插入数据
	list->Insert_LinkList(p1, 0);
	list->Insert_LinkList(p2, 0);
	list->Insert_LinkList(p3, 0);
	list->Insert_LinkList(p4, 0);
	list->Insert_LinkList(p5, 0);

	//打印数据
	list->Print_LinkList();
	cout<<"------------------"<<endl;
	//按位置删除
	list->RemoveByPos_LinkList(1);

	//按值删除
	Person pp("bbb", 20);
	list->RemoveByValue_LinkList(pp);
	//打印数据
	list->Print_LinkList();

	cout << "------------------" << endl;
	//返回第一个结点
	Person pret = list->Front_LinkList();
	cout << "姓名为: "<<pret.m_Name << " 年龄为: " <<pret.m_Age<< endl;

	//查找
	Person pAim("ccc", 30);
	cout << "找到的位置为: " << list->Find_LinkList(pAim) << endl;

	//返回链表长度
	cout << "链表长度为: " << list->Size_LinkList() << endl;

	//清空链表
	list->Clear_LinkList();
	//返回链表长度
	cout << "链表长度为: " << list->Size_LinkList() << endl;

	delete list;
}

int main()
{
	//test01();
	test02();

	system("pause");
	return 0;
}

test01()测试结果:

test02()测试结果

 

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值