C++实现单链表

单项链表实现

1、头文件

首先创建LinkList.h头文件,一般类的声明和成员函数的实现都是分文件编写的,但这里用的是模板编程,就放在一个文件夹下了,你可以用inline内联函数实现。

#pragma once
template<class T>
class LinkNode
{
	template<class T>
	friend class LinkList;         //将链表类声明为友元,以便访问私有属性

public:
	LinkNode()
	{
		next = NULL;	//每new一个结点时,将他置空,串进链表才设next
	}
protected:
	T data;
	LinkNode<T>* next;
};

template<class T>
class LinkList
{
public:
	LinkList();
	~LinkList();

	//在第k个位置插入元素x,返回插入后的线性表
	LinkList<T>& insert(int k, const T& x);
	//判断表是否为空,空返回true
	bool isEmpty() const;
	//返回表中的元素个数
	int getLength() const;
	//将表中第k个元素保存到x中,若不存在则返回false
	bool getData(int k, T& x);
	//将表中第k个元素修改为x,若不存在则返回false
	bool modifyData(int k, const T& x);
	//返回x在表中的位置,如果不在表里返回0
	int find(const T& x);

	//按位置删除第k个元素,并把它保存到x中,返回删除后的线性表
	LinkList<T>& removebyIndex(const int k, T& x);
	//按元素删除查找的元素,并把它保存到y中,返回删除后的线性表
	LinkList<T>& removebyValue(const T& x, T& y);

	void outPut(ostream& out) const;

protected:
	LinkNode<T>* head;	//指向链表的头结点指针
};

template<class T>
LinkList<T>::LinkList()
{
	//创建空单向链表
	head = new LinkNode<T> ();  //创建头结点
}

template<class T>
LinkList<T>::~LinkList()
{
	T x;
	int len = getLength();
	for (int i = len; i > 0; i--)
	{
		removebyIndex(i, x);
	}
}


template<class T>
LinkList<T>& LinkList<T>::insert(int k, const T& x)
{
	LinkNode<T>* newNode = new LinkNode<T>;		//创建待插入的新结点
	newNode->data = x;							//赋值data
	
	int len = getLength();
	if (k<1 || k>len + 1)
	{
		cout << "元素下标越界,插入失败!" << endl;
		return *this;
	}

	LinkNode<T>* p = head;						//找到头结点
	for (int i = 1; i < k; i++)					//遍历找到插入位置的前驱结点(k-1)位置
	{
		p = p->next;
	}
	//核心
	newNode->next = p->next;
	p->next = newNode;

	return *this;
}

template<class T>
bool LinkList<T>::isEmpty() const
{
	return head->next == NULL;
}

template<class T>
int LinkList<T>::getLength() const
{
	int len = 0;
	LinkNode<T>* p = head->next;	//从第一个有元素的位置开始遍历
	while (p)
	{
		len++;
		p = p->next;
	}
	return len;
}

template<class T>
bool LinkList<T>::getData(int k, T& x)
{
	if (k<0 || k>getLength())
	{
		cout << "元素下标越界,未找到该位置!" << endl;
		return false;
	}

	LinkNode<T>* p = head ->next;				//找到第一个有元素的结点
	for (int i = 1; i < k; i++)					//遍历找到插入位置的前驱结点(k-1)位置
	{
		p = p->next;
	}
	x = p->data;		//将p的信息赋值给x

	return true;
}

template<class T>
bool LinkList<T>::modifyData(int k, const T& x)
{
	if (k<0 || k>getLength())
	{
		cout << "元素下标越界,未找到该位置!" << endl;
		return false;
	}

	LinkNode<T>* p = head->next;				//找到第一个有元素的结点
	for (int i = 1; i < k; i++)					//遍历找到插入位置的前驱结点(k-1)位置
	{
		p = p->next;
	}
	p->data = x;		//将p的信息修改为x
	return true;
}

template<class T>
int LinkList<T>::find(const T& x)
{
	LinkNode<T>* p = head->next;				//指向第一个有元素的结点
	int index = 0;								//记录找到元素的下标
	while (p != NULL && p->data != x)
	{
		p = p->next;
		index++;
	}
	if (p != NULL)
	{
		return index;
	}
	else
		return 0;
}

template<class T>
LinkList<T>& LinkList<T>::removebyIndex(const int k, T& x)
{
	if ( k<1 || k>getLength() + 1 )
	{
		cout << "元素下标越界,删除失败!" << endl;
	}

	getData(k, x);
	//cout << x << endl;		//测试

	LinkNode<T>* p = head;						//找到头结点
	for (int i = 1; i < k; i++)					//遍历找到插入位置的前驱结点(k-1)位置
	{
		p = p->next;
	}
	LinkNode<T>* pDele = p->next;	//临时结点用于记录待删除结点,方便后面释放,第二个用途是直接将p->next指向pDele->next
	p->next = pDele->next;
	delete pDele;

	return *this;
}
template<class T>
LinkList<T>& LinkList<T>::removebyValue(const T& x, T& y)
{
	int index = find(x);
	if (index != 0)
	{
		return removebyIndex(index + 1, y);
	}
	else
	{
		cout << "没有此元素!" << endl;
		return *this;
	}
}


//实现顺序表的输出
template<class T>
void LinkList<T>::outPut(ostream& out) const
{
	LinkNode<T>* p = head->next;
	int len = getLength();
	for (int i = 0; i < len; i++)
	{
		out << p->data << endl;
		p = p->next;
	}
}

//全局函数
//重载运算符<<
template<class T>
ostream& operator <<(ostream& out, const LinkList<T>& x)
{
	x.outPut(out);
	return out;
}

2、测试程序

可以看出这与C++源码实现的链表在功能上还是很相像的。

#include<iostream>
using namespace std;
#include"LinkList.h"
int main()
{
	LinkList<int> list;
	list.insert(1, 10);
	list.insert(2, 70);
	list.insert(3, 20);
	list.insert(2, 1);
	list.insert(5, 6);
	list.insert(6, 3);
	cout << list << endl;

	list.modifyData(6, 100);
	cout << list << endl;
	int i = list.find(100);
	cout << i << endl;

	int x = 0;
	list.removebyIndex(4, x);	//这里删除的是第四个位置的数据,不是下标为四的数据
	cout << list << endl;
	list.removebyValue(70, x);
	cout << list << endl;

	return 0;
}

  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值