[C++] 模板类实现简单链表
听老师的话,首先建了一个头文件置放状态字,如下
ConstHeader.h
#ifndef TRUE
#define TRUE 1
#endif // TRUE
#ifndef FALSE
#define FALSE 0
#endif // FALSE
#ifndef OK
#define OK 1
#endif // OK
#ifndef ERROR
#define ERROR 0
#endif // ERROR
#ifndef INFEASIBLE
#define INFEASIBLE -1
#endif // INFEASIBLE
#ifndef OVERFLOW
#define OVERFLOW -2
#endif // OVERFLOW
typedef int Status;
然后就开始链表的构建了。首先,先明确我们的链表包括那些数据以及操作
数据
- 存放长度的 length 域
- 链表节点 LinkNode
链表节点
- 数据 data 域
- 指针 next、pre域
操作
- 初始化一个空链表(也就是个头指针)
- 初始化一个单元素链表
- 初始化一个多元素链表
- 返回头节点
- 返回尾节点
- 链表尾追加一个元素
- 销毁链表
- 获得某个位置的元素
- 在某个位置左边插入元素
- 在某个元素右边插入元素
- 删除某个位置的元素
- 获得某个元素的位置
- 遍历并打印链表
下面是该链表头文件源码:
LinkList_in_cpp.h
#pragma once
#ifndef LINKLIST_IN_CPP_H
#define LINKLIST_IN_CPP_H
#endif // LINKLIST_IN_CPP
#include <iostream>
#include "ConstHeader.h"
using namespace std;
template<class T>
class LinkNode
{
public:
//用作头指针
LinkNode();
//建立一个一般节点
LinkNode(const T &x);
//移除该节点后面一个节点,并返回该节点
LinkNode<T>* removeNextNode();
//移除该节点后面所有节点,并返回第一个节点
LinkNode<T>* removeAfterNode();
T data;
LinkNode<T> *next, *pre;
};
template<class T>
LinkNode<T>::LinkNode()
{
next = NULL;
pre = NULL;
}
template<class T>
LinkNode<T>::LinkNode(const T& x)
{
data = x;
next = NULL;
pre = NULL;
}
template<class T>
LinkNode<T>* LinkNode<T>::removeNextNode()
{
LinkNode<T>* temp = next;
next = temp.next;
return temp;
}
template<class T>
LinkNode<T>* LinkNode<T>::removeAfterNode()
{
LinkNode<T>* temp = next;
next = NULL;
return temp;
}
template<class T>
class LinkList
{
public:
//
LinkList() {
head = new LinkNode<T>();
tail = head;
};
//
LinkList(const T &x) {
head = new LinkNode<T>();
LinkNode<T>* t = new LinkNode<T>(x);
head->next = t;
t->pre = head;
tail = t;
};
//
LinkList(T a[], int n) {
LinkNode<T>* p = head, t;
for (int i = 0; i < n; i++)
{
t = new LinkNode<T>(a[i]);
p->next = t;
t->pre = p;
p = t;
}
length = n;
tail = p;
};
//
~LinkList() { Destroy(); };
//
LinkNode<T>* getHead();
//
LinkNode<T>* getTail();
//
Status Append(const T &x);
//
Status elemGet(int n, T &data);
//
Status elemLInsert(int n, const T &x);
//
Status elemRInsert(int n, const T &x);
//
Status elemDelete(int n, T &data);
//
int elemLocate(const T &x);
//
Status Destroy();
//
void Print();
private:
LinkNode<T>* head, *tail;
int length = 0;
};
template<class T>
LinkNode<T>* LinkList<T>::getHead()
{
return head;
}
template<class T>
LinkNode<T>* LinkList<T>::getTail()
{
return tail;
}
template<class T>
Status LinkList<T>::elemGet(int n, T &data)
{
LinkNode<T>* p = head;
for (int i = 0; i < n; i++)
{
if (!(p = p->next))
return ERROR;
}
if (p) data = p->data;
return OK;
}
template<class T>
Status LinkList<T>::elemLInsert(int n, const T &x)
{
LinkNode<T>* p = head;
for (int i = 0; i < n; i++)
{
if (!(p = p->next))
return ERROR;
}
LinkNode<T>* t = new LinkNode<T>(x);
if (p->pre)
{
t->next = p;
t->pre = p->pre;
p->pre->next = t;
p->pre = t;
}
else
{
t->pre = NULL;
t->next = p;
p->pre = t;
head = t;
}
length++;
return OK;
}
template<class T>
Status LinkList<T>::elemRInsert(int n, const T &x)
{
LinkNode<T>* p = head;
for (int i = 0; i < n; i++)
{
if (!(p = p->next))
return ERROR;
}
LinkNode<T>* t = new LinkNode<T>(x);
if (p->next)
{
t->pre = p;
t->next = p->next->next;
p->next = t;
t->next->pre = t;
}
else
{
t->pre = p;
t->next = NULL;
p->next = t;
tail = t;
}
length++;
return OK;
}
template<class T>
Status LinkList<T>::elemDelete(int n, T &data)
{
LinkNode<T>* p = head;
for (int i = 0; i < n; i++)
{
if (!(p = p->next))
return ERROR;
}
if (p->next)
{
p->pre->next = p->next;
p->next->pre = p->pre;
data = p->data;
}
else
{
p->pre->next = NULL;
data = p->data;
tail = p->pre;
}
delete(p);
length--;
return OK;
}
template<class T>
int LinkList<T>::elemLocate(const T &x)
{
LinkNode<T>* p = head;
for (int i = 0; p != NULL; i++)
{
if (p->data == x)
{
return i;
}
}
return -1;
}
template<class T>
Status LinkList<T>::Append(const T &x)
{
LinkNode<T> *p = new LinkNode<T>(x);
if (!p)return ERROR;
p->pre = tail;
p->next = NULL;
tail = p;
length++;
return OK;
}
template<class T>
Status LinkList<T>::Destroy()
{
LinkNode<T> *p1 = head,*p2 = head->next;
if (!p1)return ERROR;
while (p2 != NULL)
{
p1->pre = NULL;
p1->next = NULL;
delete(p1);
p1 = p2;
p2 = p2->next;
}
p1->pre = NULL;
p1->next = NULL;
delete(p1);
delete(p2);
length = 0;
return OK;
}
template<class T>
void LinkList<T>::Print() {
LinkNode<T>* p = head->next;
while (p != NULL)
{
cout << p->data << endl;
p = p->next;
}
}