由于顺序表的插入删除操作需要移动大量的元素,影响了运行效率,因此引入了线性表的链式存储——单链表。单链表通过一组任意的存储单元来存储线性表中的数据元素,不需要使用地址连续的存储单元,因此它不要求在逻辑上相邻的两个元素在物理位置上也相邻。
单链表的特点:
优点:
缺点:
创建一个类
template // T为单链表存储的元素类型
class linkList
{
private:
struct Node
{
public:
T data; // 结点的数据域
Node* next; // 结点的指针域,指向后继结点
Node(const T value, Node* p = NULL) // 具有两个参数的Node构造函数
{
data = value;
next = p;
}
Node(Node* p = NULL) // 具有一个参数的Node构造函数
{
next = p;
}
};
Node* head; // 单链表的头指针
Node* tail; // 单链表的尾
int curLength; // 单链表的当前长度
Node* getPosition(int i)const; // 返回指向单链表中第i个元素的指针
public:
linkList(); // 构造函数
~linkList(); // 析构函数
void clear(); // 将单链表清空,使之成为空表
bool empty()const; // 判空
int size(); // 返回单链表的当前实际长度
void insert(int i, const T& value); // 在位置i上插入一个元素value,表的长度增1
void remove(int i); // 删除位置i上的元素value,若删除位置合法,表的长度减1
int search(const T& value)const; // 查找值为value的元素第一次出现的位序
T visit(int i)const; // 访问位序为i的元素值,“位序”0表示第一个元素,类似于数组下标
void traverse()const; // 遍历单链表
void headCreate(); // “头插法”
void tailCreate(); // “尾插法”
void inverse(); // 逆置单链表
int prior(const T& value)const; // 查找值为value的元素的前驱
};
代码实现:
template
linkList::linkList()
{
head = tail = new Node(); // 创建带有头结点的空表
curLength = 0;
}
头插法建立单链表是说将新结点插入到当前链表的表头,即头结点之后。
思路:输入一个结束标志flag,使用一个while循环,判断条件是 value != flag
代码实现:
template // 头插法创建
void linkList::headCreate()
{
Node* p;
T value, flag;
cin >> flag; // 输入结束标志
cin >> value;
while (value != flag)
{
p = new Node(value);
p->next = head->next;
head->next = p;
curLength++;
cin >> value;
}
}
尾插法建立单链表,就是将新结点插入到当前链表的表尾。
代码实现:
template // 尾插法创建链表
void linkList ::tailCreate()
{
Node* p;
T value, flag;
cin >> flag; // 输入结束标志
cin >> value;
while (value != flag)
{
p = new Node(value);
tail->next = p;
tail = p;
curLength++;
cin >> value;
}
}
代码实现:
template
void linkList ::traverse()const
{
Node* p = head->next;
while (p != nullptr)
{
cout << p->data << " ";
p = p->next;
}
cout << endl;
}
代码实现:
template
int linkList::size()
{
return curLength;
}
代码实现:
template
int linkList ::search(const T& value)const
{
Node* current = head->next;
int i = 0;
while (current != nullptr)
{
if (current->data == value)
{
break;
}
else
{
current = current->next;
i++;
}
}
if (current != nullptr)
{
return i;
}
return -1;
}
代码实现:
template // 访问位序为i的元素返回其数据域
T linkList ::visit(int i)const
{
if (i < 0 || i>(curLength - 1))
{
T a = 0;
return a;
}
Node* current = head->next;
while (i--)
{
current = current->next;
}
return current->data;
}
返回指向单链表中第i个元素的指针
template
typename linkList ::Node* linkList ::getPosition(int i)const
{
Node* ptemp = head;
int k = 0;
while (k < i)
{
ptemp = ptemp->next;
k++;
}
return ptemp;
}
代码实现:
template
void linkList ::insert(int i, const T& value)
{
Node* current = getPosition(i);
Node* newNode = new Node(value);
newNode->next = current->next;
current->next = newNode;
curLength++;
}
代码实现:
template
void linkList::remove(int i)
{
Node* current = getPosition(i);
Node* del = current->next;
current->next = del->next;
delete del;
curLength--;
}
代码实现:
template
bool linkList::empty()const
{
return head->next == nullptr;
}
#include
template // T为单链表存储的元素类型
class linkList
{
private:
struct Node
{
public:
T data; // 结点的数据域
Node* next; // 结点的指针域,指向后继结点
Node(const T value, Node* p = NULL) // 具有两个参数的Node构造函数
{
data = value;
next = p;
}
Node(Node* p = NULL) // 具有一个参数的Node构造函数
{
next = p;
}
};
Node* head; // 单链表的头指针
Node* tail; // 单链表的尾
int curLength; // 单链表的当前长度
Node* getPosition(int i)const; // 返回指向单链表中第i个元素的指针
public:
linkList(); // 构造函数
~linkList(); // 析构函数
void clear(); // 将单链表清空,使之成为空表
bool empty()const; // 判空
int size(); // 返回单链表的当前实际长度
void insert(int i, const T& value); // 在位置i上插入一个元素value,表的长度增1
void remove(int i); // 删除位置i上的元素value,若删除位置合法,表的长度减1
int search(const T& value)const; // 查找值为value的元素第一次出现的位序
T visit(int i)const; // 访问位序为i的元素值,“位序”0表示第一个元素,类似于数组下标
void traverse()const; // 遍历单链表
void headCreate(); // “头插法”
void tailCreate(); // “尾插法”
void inverse(); // 逆置单链表
int prior(const T& value)const; // 查找值为value的元素的前驱
};
template
linkList::linkList()
{
head = tail = new Node(); // 创建带有头结点的空表
curLength = 0;
}
template
linkList::~linkList()
{
clear();
delete head; // 删除头结点
}
template
bool linkList::empty()const
{
return head->next == nullptr;
}
template
int linkList::size()
{
return curLength;
}
template
void linkList::clear()
{
Node* p = head->next;
while (p)
{
head = head->next;
delete p;
p = head;
}
}
template
typename linkList ::Node* linkList ::getPosition(int i)const
{
Node* ptemp = head;
int k = 0;
while (k < i)
{
ptemp = ptemp->next;
k++;
}
return ptemp;
}
template
void linkList ::insert(int i, const T& value)
{
Node* current = getPosition(i);
Node* newNode = new Node(value);
newNode->next = current->next;
current->next = newNode;
curLength++;
}
template
void linkList::remove(int i)
{
Node* current = getPosition(i);
Node* del = current->next;
current->next = del->next;
delete del;
curLength--;
}
template
void linkList ::traverse()const
{
Node* p = head->next;
while (p != nullptr)
{
cout << p->data << " ";
p = p->next;
}
cout << endl;
}
template
int linkList ::search(const T& value)const
{
Node* current = head->next;
int i = 0;
while (current != nullptr)
{
if (current->data == value)
{
break;
}
else
{
current = current->next;
i++;
}
}
if (current != nullptr)
{
return i;
}
return -1;
}
template // 访问位序为i的元素返回其数据域
T linkList ::visit(int i)const
{
if (i < 0 || i>(curLength - 1))
{
T a = 0;
return a;
}
Node* current = head->next;
while (i--)
{
current = current->next;
}
return current->data;
}
template // 头插法创建
void linkList::headCreate()
{
Node* p;
T value, flag;
cin >> flag; // 输入结束标志
cin >> value;
while (value != flag)
{
p = new Node(value);
p->next = head->next;
head->next = p;
curLength++;
cin >> value;
}
}
template // 尾插法创建链表
void linkList ::tailCreate()
{
Node* p;
T value, flag;
cin >> flag; // 输入结束标志
cin >> value;
while (value != flag)
{
p = new Node(value);
tail->next = p;
tail = p;
curLength++;
cin >> value;
}
}
template // 头插法逆置
void linkList ::inverse()
{
Node* temp = nullptr;
Node* p = head->next;
head->next = nullptr;
while (p != nullptr)
{
temp = p;
p = p->next;
temp->next = head->next;
head->next = temp;
}
}
template
int linkList ::prior(const T& value)const
{
Node* current = head->next;
int a = 0;
Node* p = nullptr;
while (current != nullptr)
{
if (current->data == value)
{
break;
}
else
{
current = current->next;
a++;
}
}
if (current != nullptr)
{
return a - 1;
}
return -1;
}
#include
using namespace std;
#include"SList.h"
int main()
{
linkList* lk1, * lk2;
lk1 = new linkList();
lk2 = new linkList();
int i;
int val;
lk1->headCreate(); // 测试头插法创建单链表
lk2->tailCreate(); // 测试尾插法创建单链表
lk1->traverse(); // 测试遍历
lk2->traverse(); // 测试遍历
cout << "查找值为2的位序:" << lk1->search(2) << endl;
cout << "查找位序为2的值" << lk1->visit(2) << endl;
cout << "长度:" << lk1->size();
return 0;
}