线性表链式存储结构特点是:用一组任意的存储单元存储线性表的数据元素(这组存储单元可以是连续的,也可以是不连续的)
谨以此文记录单链表的实现:
#include <iostream>
using namespace std;
typedef int ElemType;
typedef struct LNode
{
ElemType data;
LNode *next;
} LNode, *LinkList;
void printUI()
{
cout << "可执行操作有:" << endl;
cout << "*****************************************" << endl;
cout << "******* 1.初始化或重置链表 *******" << endl;
cout << "******* 2.销毁链表 *******" << endl;
cout << "******* 3.链表中数据元素个数 *******" << endl;
cout << "******* 4.所指位序的元素值 *******" << endl;
cout << "******* 5.链表已存在元素的位序 *******" << endl;
cout << "******* 6.请输入元素,求直接前驱 *******" << endl;
cout << "******* 7.请输入元素,求直接后继 *******" << endl;
cout << "******* 8.在第i个位置插入元素 *******" << endl;
cout << "******* 9.删除第i个元素 *******" << endl;
cout << "******* 10.输出所输入的链表元素 *******" << endl;
cout << "******* 11.初始化并输入链表元素 *******" << endl;
cout << "******* 12.退出 *******" << endl;
cout << "*****************************************" << endl;
}
/**
* @brief 初始化链表,返回是否成功
*
* @param L
* @return true
* @return false
*/
bool InitList_L(LinkList &L)
{
L = new LNode;
if (!L)
return false;
L->next = nullptr;
return true;
}
/**
* @brief 销毁链表,返回是否成功
*
* @param L
* @return true
* @return false
*/
bool DestroyList_L(LinkList &L)
{
LinkList p;
while (L)
{
p = L;
L = L->next;
delete p;
}
return true;
}
/**
* @brief 清空链表,返回是否成功
*
* @param L
* @return true
* @return false
*/
bool ClearList(LinkList &L)
{
LinkList p, q;
p = L->next;
while (p)
{
q = p->next;
delete p;
p = q;
}
L->next = nullptr;
return true;
}
/**
* @brief 获取链表长度
*
* @param L
* @return int
*/
int ListLength_L(LinkList L)
{
LinkList p;
p = L->next;
int count = 0;
while (p)
{
count++;
p = p->next;
}
return count;
}
/**
* @brief 判断表是否为空
*
* @param L
* @return true
* @return false
*/
bool ListEmpty(LinkList L)
{
if (L->next == nullptr)
return true;
else
return false;
}
/**
* @brief 取链表L的第i个元素赋值到e,成功返回true
*
* @param L
* @param i
* @param e
* @return true
* @return false
*/
bool GetElem_L(LinkList L, int i, ElemType &e)
{
LinkList p = L->next;
int j = 1;
while (p && j < i)
{
p = p->next;
j++;
}
if (!p || j > i)
return false;
e = p->data;
return true;
}
/**
* @brief 在链表L中查找元素e的地址
*
* @param L
* @param e
* @return LNode*
*/
LNode *LocateElem_L(LinkList L, ElemType e)
{
LinkList p = L->next;
while (p && p->data != e)
p = p->next;
return p;
}
/**
* @brief 在链表L中查找元素e的下标
*
* @param L
* @param e
* @return int
*/
int LocateElem(LinkList L, ElemType e)
{
LinkList p = L->next;
int cnt = 1;
while (p && p->data != e)
{
p = p->next;
cnt++;
}
return cnt;
}
/**
* @brief 在链表L的i位置插入一个元素e
*
* @param L
* @param i
* @param e
* @return true
* @return false
*/
bool ListInsert_L(LinkList &L, int i, ElemType e)
{
LinkList p = L;
int j = 0;
while (p && j < i - 1)
{
p = p->next;
j++;
}
if (!p || j > i - 1)
return false;
LNode *s = new LNode;
s->data = e;
s->next = p->next;
p->next = s;
return true;
}
/**
* @brief 删除链表L中位置i的元素,并将其数据用e返回
*
* @param L
* @param i
* @param e
* @return true
* @return false
*/
bool ListDelete_L(LinkList &L, int i, ElemType &e)
{
LinkList p = L;
int j = 0;
while (p->next && j < i - 1)
{
p = p->next;
j++;
}
if (!(p->next) || j > i - 1)
return false;
LinkList r = p->next;
p->next = r->next;
e = r->data;
delete r;
return true;
}
/**
* @brief 创建长度为n的链表,并填入数据(前插法)
*
* @param L
* @param n
*/
void CreateList_H(LinkList &L, int n)
{
L = new LNode;
L->next = nullptr;
while (n--)
{
LNode *p = new LNode;
cin >> p->data;
p->next = L->next;
L->next = p;
}
}
/**
* @brief 创建长度为n的链表,并填入数据(后插法)
*
* @param L
* @param n
*/
void CreateList_R(LinkList &L, int n)
{
L = new LNode;
L->next = nullptr;
LinkList r = L;
while (n--)
{
LNode *p = new LNode;
cin >> p->data;
p->next = nullptr;
r->next = p;
r = p;
}
}
/**
* @brief 输出链表所有元素
*
* @param L
*/
void ShowList(LinkList L)
{
LinkList p = L->next;
while (p)
{
cout << p->data << " ";
p = p->next;
}
cout << endl;
}
/**
* @brief 求La和Lb的并集放到La
*
* @param La
* @param Lb
*/
void UnionList(LinkList &La, LinkList Lb)
{
int La_len = ListLength_L(La);
int Lb_len = ListLength_L(Lb);
for (int i = 1; i <= Lb_len; i++)
{
ElemType e;
GetElem_L(Lb, i, e);
if (!LocateElem_L(La, e))
ListInsert_L(La, ++La_len, e);
}
}
int main()
{
int mode, i;
ElemType e;
LinkList L = nullptr;
printUI();
while (true)
{
cout << "请输入你的选择:";
cin >> mode;
if (mode == 12)
break;
if (mode < 1 || mode > 12)
{
cout << "操作不存在" << endl;
continue;
}
if (!L && mode != 1 && mode != 11)
{
cout << "链表未初始化" << endl;
continue;
}
switch (mode)
{
case 1:
if (InitList_L(L))
cout << "初始化成功" << endl;
else
cout << "初始化失败" << endl;
break;
case 2:
if (DestroyList_L(L))
cout << "销毁成功" << endl;
else
cout << "销毁失败" << endl;
break;
case 3:
cout << "数据元素个数为" << ListLength_L(L) << endl;
break;
case 4:
cout << "请输入所指位序: ";
cin >> i;
if (GetElem_L(L, i, e))
cout << "该位置元素为" << e << endl;
else
cout << "获取失败" << endl;
break;
case 5:
cout << "请输入所查元素:";
cin >> e;
cout << "该元素位序为" << LocateElem(L, e) << endl;
break;
case 6:
cout << "请输入所查元素:";
cin >> e;
i = LocateElem(L, e);
if (i == 1)
cout << "该元素无前驱" << endl;
else if (GetElem_L(L, i - 1, e))
cout << "该元素前驱为" << e << endl;
else
cout << "获取失败" << endl;
break;
case 7:
cout << "请输入所查元素:" << endl;
cin >> e;
i = LocateElem(L, e);
if (i == ListLength_L(L))
cout << "该元素无后继" << endl;
else if (GetElem_L(L, i + 1, e))
cout << "该元素后继为" << e << endl;
else
cout << "获取失败" << endl;
break;
case 8:
cout << "请输入插入元素:";
cin >> e;
cout << "请输入插入位置:";
cin >> i;
if (ListInsert_L(L, i, e))
cout << "插入成功" << endl;
else
cout << "插入失败" << endl;
break;
case 9:
cout << "请输入要删除的位置:";
cin >> i;
if (ListDelete_L(L, i, e))
cout << "删除成功" << endl;
else
cout << "删除失败" << endl;
break;
case 10:
ShowList(L);
break;
case 11:
cout << "请输入链表长度:";
cin >> i;
cout << "请输入元素:";
CreateList_R(L, i);
break;
}
}
return 0;
}