简单链表的实现
#include <iostream>
#include <string>
using namespace std;
#define OK 1 // 操作成功
#define ERROR 0 // 操作失败
typedef int Status; // 返回操作的执行状态
//定义学生信息的数据类型,即为链式存储中每个节点中存放的信息
typedef struct
{
int id;
int age;
string name;
} ElemType;
// 线性链表声明
typedef struct Node
{
ElemType data; // 数据
struct Node *next; // 指项下一个结点的指针
} Node, *LinkList;
// 线性链表的初始化,空表但已经分配地址空间
Status InitLinkList(LinkList &L)
{
L = new Node; // 申请一个Node
L->next = NULL;
return OK;
}
// 销毁线性链表
Status Destory(LinkList L)
{
Node *p;
while (L)
{ // 判断是否到达链表尾部
p = L;
L = L->next;
delete p;
}
return OK;
}
// 清空线性链表
Status Clear(LinkList L)
{
Node *p = L->next;
// 可以直接在此处直接调用Destroy(p),后面代码省略
Node *q;
while (p)
{ // 判断是否到达线性链表尾部
q = p;
p = p->next;
delete q;
}
L->next = NULL;
return OK;
}
//判断线性链表是否为空
bool isEmpty(LinkList L)
{
if (L->next)
{
return false;
}
else
{
return true;
}
}
// 求取线性链表表长
int Length(LinkList L)
{
int j = 0;
while (L->next) // 判断是否指到链表末尾
{
j++;
L = L->next;
}
return j;
}
// 获取第i个元素
Status GetElem(LinkList L, int i, ElemType &e)
{
Node *p = L->next;
int j = 1;
while (p && j < i)
{ // p为空表示i超出链表长度,j>i表示i的值非法,及对应i值大于表长或者非正
j++;
p = p->next;
}
if (!p || j > i)
{ // 第i个元素不存在
return ERROR;
}
e = p->data;
return OK;
}
// 改变第i个元素的data
Status SetElem(LinkList L, int i, ElemType e)
{
Node *p = L->next;
int j = 1;
while (p && j < i)
{ // p为空表示i超出链表长度,j>i表示i的值非法,及对应i值大于表长或者非正
j++;
p = p->next;
}
if (!p || j > i)
{ // 第i个元素不存在
return ERROR;
}
p->data = e;
return OK;
}
// 按值查找(返回地址)
Node *Inquire_P(LinkList L, ElemType e)
{
Node *p = L->next;
while (p && p->data.id != e.id)
{
p = p->next;
}
return p;
}
// 按值查找(返回位置)
int Inquire_N(LinkList L, ElemType e)
{
Node *p = L->next;
int j = 1;
while (p)
{
if (p->data.id == e.id)
{
return j;
}
p = p->next;
j++;
}
return -1; // 返回-1表示查找失败
}
// 在第i个结点前插入一个值为e的新结点
Status Insert(LinkList L, int i, ElemType e)
{
// 插入的合法位置位1~Length(L)+1;
Node *p = L;
int j = 0;
// 查找指向第i-1个结点的指针
while (p && j < i - 1)
{
p = p->next;
j++;
}
if (!p || j > i - 1)
{
return ERROR;
}
// 插入新的结点
Node *temp = new Node;
temp->data = e;
temp->next = p->next;
p->next = temp;
return OK;
}
// 线性链表的删除
Status Delete(LinkList L, int i, ElemType &e)
{
// 删除的合法位置位为1~Length(L);
Node *p = L;
int j = 0;
while (p->next && j < i - 1)
{
p = p->next;
j++;
}
if (!(p->next) || j > i - 1)
{ // 防止i的位置不合理
return ERROR;
}
Node *temp = p->next;
p->next = temp->next;
e = temp->data;
delete temp;
return OK;
}
// 头插法
void CreatList_H(LinkList &L, int n)
{
L = new Node;
L->next = NULL;
for (int i = n; i > 0; i--)
{
Node *p = new Node;
cin >> p->data.age >> p->data.id >> p->data.name;
p->next = L->next;
L->next = p;
}
}
// 尾插法
void CreatList_R(LinkList &L, int n)
{
L = new Node;
L->next = NULL;
Node *r = L;
for (int i = 0; i < n; i++)
{
Node *p = new Node;
cin >> p->data.age >> p->data.id >> p->data.name;
p->next = NULL;
r->next = p;
r = p;
}
}
// 线性链表倒置(通过修改每个节点中的数据)
void Reverse_NUM(LinkList &L)
{
ElemType a, b;
int length = Length(L);
for (int i = 1; i <= length / 2; i++)
{
GetElem(L, i, a);
GetElem(L, length - i + 1, b);
SetElem(L, i, b);
SetElem(L, length - i + 1, a);
}
}
// 线性链表倒置(通过指针来倒置链表,不修该数据)
void Reverse_Ptr(LinkList &L)
{
Node *p, *q, *r;
p = L->next;
q = p;
r = NULL;
while (p != NULL)
{
p = p->next;
q->next = r;
r = q;
q = p;
}
L->next = r;
}
// 遍历所有元素
void Traverse(LinkList L)
{
Node *p = L->next;
while (p)
{
cout << p->data.age << " " << p->data.id << " " << p->data.name << endl;
p = p->next;
}
cout << endl;
}
int main()
{
LinkList L;
CreatList_H(L, 5);
Traverse(L);
cout << "------------------------------------------------------" << endl;
;
Reverse_Ptr(L);
Traverse(L);
cout << "------------------------------------------------------" << endl;
Reverse_NUM(L);
Traverse(L);
cout << "------------------------------------------------------" << endl;
ElemType a;
a.age = 100;
a.id = 200;
a.name = "chnee";
Insert(L, Length(L) + 1, a);
a.id = 250;
Insert(L, Length(L), a);
Traverse(L);
cout << "------------------------------------------------------" << endl;
return 0;
}
参考书目《数据结构 严蔚敏第二版》