单向链表CPP实现
1、单项链表原理
单项链表是一种线性表,由各个节点组成。节点中包含两种,一种数据域,一种指针域 ,二者放在了一起。插入新的节点需要自己的开辟内存,同时删除需要free内存。
2、单向链表CPP实现
2.1 lineList.h文件
#pragma once
#include <iostream>
template <class DataType>
struct LineNode {
public:
DataType data; //存放数据
LineNode<DataType>* next; //用于指向下一个数据
};
template<class DataType>
class LineList {
public:
LineList();//建立一个只有头节点的单链表
LineList(DataType data[],int n);//建立一个有n个元素的单链表
~LineList();//析构函数
int getLineSize();//获取链表的长度
DataType getLineData(int pos);//获取单链表某个位置的数据
int findLineData(DataType value);//获取某个数据的位置
void insertData(int pos ,DataType data);//从某个位置插入某个数据
void deleteData(int pos);//删除某个位置上面的数据
bool isEmpty();//判断是否为空
void printLine();//遍历整个单链表
private:
LineNode<DataType>* head; //单链表的头节点指针
int lineSize; //链表的元素长度
};
template<class DataType>
inline LineList<DataType>::LineList() {
//创建头节点
head = new LineNode<DataType>;
head->next = nullptr;
this->lineSize = 0;
}
template<class DataType>
LineList<DataType>::LineList(DataType data[], int n) {
head = new LineNode<DataType>;//生成头节点
LineNode<DataType>* p = head, * s = nullptr;//其中s是新节点,存放新数据
this->lineSize = 0;
for (int i = 0; i < n; i++) {
s = new LineNode<DataType>;
s->data = data[i];
//将新的节点插入到链表中
p->next = s;
p = s;
this->lineSize++;
}
p->next = nullptr;
}
template<class DataType>
LineList<DataType>::~LineList() {
LineNode<DataType>* p = head;//临时存储依次析构的指针
while (head != nullptr) {
head = head->next;
delete p;
p = head;
}
}
template<class DataType>
int LineList<DataType>::getLineSize() {
return this->lineSize;
}
template<class DataType>
DataType LineList<DataType>::getLineData(int pos) {
LineNode<DataType>* p = head->next;//临时指针
int i = 0;//计数
while (p != nullptr) {
if (pos == i) {
return p->data;
}
i++;
p = p->next;//指向下一个
}
}
template<class DataType>
int LineList<DataType>::findLineData(DataType value) {
LineNode<DataType>* p = head->next;
int i = 0;
while (p != nullptr) {
if (p->data == value) {
break;
}
i++;
p = p->next;//指向下一个
}
return i;
}
template<class DataType>
void LineList<DataType>::insertData(int pos, DataType data) {
LineNode<DataType>* p = head, * s = nullptr;
int i = 0;
while (p != nullptr) {
if (pos == i) {//添加新的节点
s = new LineNode<DataType>;
s->data = data;
s->next = p->next;
p->next = s;
this->lineSize++;
}
i++;
p = p->next;//指向下一个节点
}
}
template<class DataType>
void LineList<DataType>::deleteData(int pos) {
LineNode<DataType>* p = head, * s = nullptr;
int i = 0;
while (p != nullptr) {
s = p->next;//临时存储需要删除的数据
if (pos == i && s != nullptr) {
p->next = s->next;//使得链条去点一个节点后链接
delete s;
this->lineSize--;
}
i++;
p = p->next;//指向下一个节点
}
}
template<class DataType>
bool LineList<DataType>::isEmpty() {
if (this->lineSize <= 0) {
return false;
}
return true;
}
template<class DataType>
void LineList<DataType>::printLine() {
LineNode<DataType>* p = head->next;
while (p != nullptr) {
std::cout << p->data << "\t";
p = p->next;//指向下一个节点
}
std::cout << std::endl;
}
注意:
上面将实现和声明写在一起的原因是,模板中声明和实现一般都放在一起,其实就是匹配过程需要注意的地方,并且通常我们会把模板的定义和实现都放在头文件中以便使用。
2.2 main.cpp试验
#include <iostream>
#include "lineList.h"
int main() {
int data[5] = { 1,2,3,4,5 };
LineList<int> list;
list.insertData(0, 12);
list.insertData(1, 13);
list.insertData(2, 14);
list.insertData(3, 17);
list.insertData(4, 15);
list.insertData(5, 10);
std::cout << list.findLineData(15) << std::endl;
std::cout << list.getLineData(2) << std::endl;
std::cout << list.getLineSize() << std::endl;
std::cout << "-------" << std::endl;
list.printLine();
list.deleteData(3);
std::cout << "-------" << std::endl;
list.printLine();
LineList<int> list1(data,5);
list1.insertData(1,8);
std::cout << "-------" << std::endl;
list1.printLine();
system("pause");
return 0;
}