#include<iostream>
using namespace std;
#define MAXSIZE 100
#define OK 1
#define ERROR 0
typedef int ElemType;
typedef int Status;
// 单链表的定义
typedef struct LNode
{
ElemType data;// 结点的数据域
struct LNode* next;// 结点的指针域
}LNode, * LinkList; // LinkList为指向结构体LNode的指针类型
// 单链表的初始化
bool InitList(LinkList& L)// LinkList &L等价于 LNode *&L,LNode *&L是一个指向指针的引用
{
L = new LNode; // 堆区开辟一个头结点,结点的数据类型为LNode
L->next = nullptr; // 空表,也就是说头结点的指针指向为空
return true;
}
// 头插法创建单向链表
void CreatListHead(LinkList& L, int n)
{
// 逆位序输入n个元素的值
L = new LNode;
L->next = nullptr; // 先建立一个带头结点的空链表
for (int i = 0; i < n; i++)
{
LNode* p = new LNode;
cin >> p->data;
p->next = L->next;
L->next = p;
}
}
// 尾插法创建单向链表
void CreatListTail(LinkList& L, int n)
{
// 正位序输入n个元素的值
L = new LNode;
L->next = nullptr; // 先建立一个带头结点的空链表
LNode* r = L;
for (int i = 0; i < n; i++)
{
LNode* p = new LNode;
cin >> p->data;
p->next = nullptr;
r->next = p;
r = p;
}
}
// 判断链表是否为空
bool IsEmpty(LinkList& L)
{
if (L->next)// 非空
{
return false;
}
else
{
return true;
}
}
// 单链表的销毁
bool DestroyList(LinkList& L)
{
//判断链表是否为空
if (IsEmpty(L))
{
cerr << "empty List!" << endl;
return false;
}
while (L)//链表还未到达尾端
{
auto temp = L->next;//将头指针指向下一个结点
delete L;
L = temp;
}
return true;
}
// 统计链表长度
int GetLength(LinkList& L)
{
LNode* p;
p = L->next;
int length = 0;
while (p)
{
length++;
p = p->next;
}
return length;
}
// 单链表的取值
bool GetElem(LinkList L, int i, ElemType& e)
{
if (i < 0)
{
cerr << "out of range" << endl;
return false;
}
LNode* p = L->next;
for (int j = 1; j < i + 1; j++)
{
p = p->next;
if (!p)
{
cerr << "out of range" << endl;
return false;//如果此时p为空,意味着已经到达链表尾端,停止循环
}
}
e = p->data;
return true;
}
// 单链表的按值查找
int LocateElem(LinkList L, ElemType e)
{
LNode* p = L->next;
int index = 1;
while (p)
{
if (p->data == e)
{
return index;
}
index++;
p = p->next;
}
cerr << "not found" << endl;
return 0;
}
// 单链表的插入
bool InsertList(LinkList& L, int i, ElemType e)
{
LNode* p = L;
int j = 0;
while (p && j < i - 1) // 停在要插入的前一个
{
p = p->next;
j++;
}
//异常判断
if (!p || i < 0) // ?????
{
cerr << "out of range" << endl;
return false;
}
LinkList insert = new LNode;
insert->data = e;
insert->next = p->next;
p->next = insert;
return true;
}
// 单链表的删除
bool ListDelete(LinkList& L, int i)
{
LNode* p = L;
int j = 0;
while (p->next && j < i - 1) // 停在要删除的前一个
{
p = p->next;
j++;
}
if (!(p->next) || i < 0)
{
cerr << "out of range" << endl;
return false;
}
LNode* q = p->next;
p->next = p->next->next;
delete q;
return true;
}
// 两个有序链表的合并
void MergeList(LinkList& LA, LinkList& LB, LinkList& LC)
{
// 已知单链表LA和LB的元素按值非递减排列
// 归并LA和LB得到新的单链表LC,LC的元素也按值非递减排列
LNode* pa = LA->next;
LNode* pb = LB->next;
LC = LA; // 用LA的头结点作为LC的头结点
LNode* pc = LC;
while (pa && pb)
{// LA和LB均未到达表尾,依次摘取两表中值较小的结点插入到LC的最后
if (pa->data <= pb->data) //尾插法,插入元素
{
//pc的指针域指向小元素的地址
pc->next = pa;
//移动pc指针,使得pc永远都指向最后链表Lc的最后一个元素
pc = pc->next;
//pa的元素使用过后,要向后移动pa
pa = pa->next;
}
else
{
//pc的指针域指向小元素的地址
pc->next = pb;
//移动pc指针,使得pc永远都指向最后链表Lc的最后一个元素
pc = pc->next;
//pb的元素使用过后,要向后移动pb
pb = pb->next;
}
}
//上面的while循环执行完毕后,较长的链表还会余留一段元素,这段元素的起始地址就是pa(或pb
pc->next = (pa ? pa : pb);
//链表合并完毕,释放Lb的头结点
delete LB;
}
// 时间复杂度为O(n),但是空间复杂度为O(1)
// 循环链表的定义
typedef struct CLnode
{
ElemType data;
struct CLnode* next;
}*CircList;
// 循环链表的初始化
void InitList(CircList& L)
{
L = new CLnode;
L->next = L;
}
/*
循环链表的最后一个结点的next不再是空指针,而是指向头结点,
因此,循环中的结束条件要发生变化
单链表--------------循环链表
while(p)--------->while(p!=L)
while(p->next)--->while(p->next!=L)
*/
// 双向链表的定义
typedef struct DuLnode
{
ElemType data;
struct DuLnode* prior;
struct DuLnode* next;
}DuLNode, * DuLinkList;
// 双向链表的初始化
void InitList(DuLinkList& L)
{
L = new DuLnode;
L->prior = nullptr;
L->next = nullptr;
}
// 头插法创建双向链表
void CreatListHead(DuLinkList& L, int n)
{
for (int i = 0; i < n; i++)
{
DuLnode* p = new DuLnode;
cin >> p->data;
p->prior = L;
p->next = L->next;
L->next = p;
if ((p->next))//如果不是第一个元素
{
L->next->prior = p;
}
}
}
// 尾插法创建双向链表
void CreatListTail(DuLinkList& L, int n)
{
DuLnode* r = L;
for (int i = 0; i < n; i++)
{
DuLnode* p = new DuLnode;
cin >> p->data;
p->prior = r;
p->next = nullptr;
r->next = p;
r = p;
}
}
// 双向链表的插入
bool ListInsert_DuL(DuLinkList& L, int i, ElemType& e)
{
//移动指针到第i个位置
DuLnode* p = L->next;
int j = 1;
while (p->next && j < i)
{
j++;
p = p->next;
}
if (j < i || j < 1) //如果i在链表范围内,上面的while循环的终止条件就是j<i
{
cerr << "out of range" << endl;
return false;
}
//在堆区创建要插入的结点
DuLnode* s = new DuLnode;
s->data = e;
//重新建立链接关系
s->prior = p->prior; //第一步:s的前趋等于p的前趋
p->prior->next = s; //第二步,用p的前趋结点的next指向插入元素s,更改了第一条链
s->next = p; //第三步:s的后继指向p
p->prior = s; //第四步:p的前趋改为指向s,更改了第二条链
//return
return true;
}
// 双向链表的删除
bool ListDelete_DuL(DuLinkList &L, int i)
{
//移动指针到i处
DuLnode* p = L->next;
int j = 1;
while (p->next && j < i)
{
j++;
p = p->next;
}
if (j < i || j < 1) //如果i在链表范围内,上面的while循环的终止条件就是j<i
{
cerr << "out of range" << endl;
return false;
}
//改变链接关系
p->prior->next = p->next;//p的前趋结点的next等于p的后继
if ((p->next))//如果删除的不是最后一个元素
{
p->next->prior = p->prior;
}
//释放p
delete p;
//结束
return true;
}
数据结构:链表(C++)
于 2024-03-06 12:23:46 首次发布