文章目录
1. 用C++实现链表
本文用到C++中的类模板,用类模板的好处就是方便建立任何类型的链表。但类模板这里有个坑就是无法分离编译,具体原因可以百度搜索类模板无法分离编译。最后废话不多说,直接上代码。
2. 代码
linklist.h文件实现顺序表的声明和定义
#ifndef LINKLIST_H
#define LINKLIST_H
#include <iostream>
using namespace std;
template <typename T>
class Node {
public:
/* 用于链表节点的定义 */
T data; // 表示数据域
Node<T> *next; // 表示指针域,存储下一个节点的位置
};
template <typename T>
class LinkList : public Node<T>{
private:
/* 用于链表的定义 */
Node<T> *head; // 头节点
public:
/* 成员函数的声明 */
LinkList(); // 重写默认的构造函数
bool Empty(); // 判断链表是否为空
int GetLen(); // 获取链表的长度
void insert(T elem); // 默认插入链表的开头
bool insert(int idx, T elem); // 在链表的指定位置插入元素
void remove(T &elem); // 默认删除链表的第一个元素,并返回该元素
bool remove(int idx, T &elem); // 删除并指定位置的元素
bool index(int idx, T &elem); // 找出并返回指定位置的元素
int index(bool (*compare(T, T)), T elem); // 找到并返回满足compare的元素
void traverse(void (* print)(T &elem)); // 用于遍历整个链表
};
/* 用于实现成员函数的定义 */
template <typename T>
inline LinkList<T>::LinkList() {
this -> head = (Node<T> *)malloc(sizeof(Node<T>));
if (!this -> head) {
cerr << "Error allocating memory!" << endl;
}
this -> head -> next = nullptr;
}
template <typename T>
inline bool LinkList<T>::Empty() {
if (this -> head == nullptr) {
return true;
}
return false;
}
template <typename T>
int LinkList<T>::GetLen() {
Node<T> *tmp = this -> head -> next;
int counter = 0;
while (tmp) {
counter++;
tmp = tmp -> next;
}
return counter;
}
template <typename T>
inline void LinkList<T>::insert(T elem) {
Node<T> *newnode = (Node<T> *)malloc(sizeof(Node<T>));
newnode -> data = elem;
newnode -> next = this -> head -> next;
this -> head -> next = newnode;
}
template <typename T>
bool LinkList<T>::insert(int idx, T elem) {
if (idx < 1 || idx > this -> GetLen() + 1) {
cerr << "subscript wrong!" << endl;
return false;
}
int counter = 0;
Node<T> *newnode = this -> head, *tmp = (Node<T> *)malloc(sizeof(Node<T>));
while (counter < idx - 1 && newnode -> next != nullptr) {
counter++;
newnode = newnode -> next;
}
tmp -> data = elem;
tmp -> next = newnode -> next;
newnode -> next = tmp;
return true;
}
template <typename T>
void LinkList<T>::remove(T &elem) {
Node<T> *tmp = this -> head -> next;
this -> head -> next = tmp -> next;
elem = tmp -> data;
free(tmp);
}
template <typename T>
bool LinkList<T>::remove(int idx, T &elem) {
if (idx < 1 || idx > this -> GetLen()) {
cerr << "subscript wrong!" << endl;
return false;
}
Node<T> *newnode = this -> head, *tmp;
int counter = 0;
while (counter < idx - 1 && newnode -> next != nullptr) {
newnode = newnode -> next;
counter++;
}
tmp = newnode -> next;
elem = tmp -> data;
newnode -> next = tmp -> next;
free(tmp);
return true;
}
template <typename T>
bool LinkList<T>::index(int idx, T &elem) {
if (idx < 1 || idx > this -> GetLen()) {
cerr << "subscript wrong!" << endl;
return false;
}
Node<T> *newnode = this -> head -> next;
int counter = 1;
while (counter < idx) {
counter++;
newnode = newnode -> next;
}
elem = newnode -> data;
return true;
}
template <typename T>
int LinkList<T>::index(bool (*compare(T, T)), T elem) {
Node<T> *newnode = this -> head;
int counter = 0;
while (newnode -> next != nullptr) {
newnode = newnode -> next;
counter++;
if (compare(newnode -> data, elem)) {
return counter;
}
}
return -1;
}
template <typename T>
void LinkList<T>::traverse(void (* print)(T &elem)) {
Node<T> *tmp = this -> head -> next;
while (tmp) {
print(tmp -> data);
tmp = tmp -> next;
}
cout << endl;
}
/* 用于定义非成员函数 */
template <typename T>
void show(LinkList<T> &L) {
cout << "length : " << L.GetLen() << endl;
}
template <typename T>
void print(T &elem) {
cout << elem << " ";
}
#endif
main.cpp文件测试顺序表
#include <iostream>
#include "linklist.h"
using namespace std;
int main(int argc, char const *argv[])
{
/* code */
LinkList<int> L;
L.insert(1);
L.insert(2);
L.insert(3);
L.insert(4);
L.insert(1,5);
L.traverse(print);
int tmp;
L.remove(5,tmp);
L.traverse(print);
L.index(5, tmp);
cout << tmp << endl;
show(L);
return 0;
}
喜欢的话,就点个关注吧。