目录
链式存储结构
- 线性表中数据元素(结点)在存储器中的位置是任意的,即:逻辑上相邻,物理位置不一定相邻
- 结点
- 链表 n个结点由指针链组成的一个链表
单链表
1.带头结点的单链表
非空表 空表
2.存储结构
3.定义
#define TRUE (1)
#define FALSE (0)
#define OK (1)
#define ERROR (0)
#define INFEASIBLE (-1)
#define OVERFLOW (-2)
typedef char ElemType;
typedef int Status;
typedef struct Lnode{
ElemType data; //数据域
struct Lnode *next; //指针域
}LNode, *LinkList;
LinkList L; //定义链表L
//LNode *p; //定义结点指针 等价于 LinkList p(一般不用);
4.初始化单链表
Status InitList_L(LinkList &L)
{
L = new LNode; // c语言:L = (LinkList)malloc(sizeof(LNode));
L->next = NULL;
return OK;
}
5.判断链表是否为空
//空表:链表中无元素,但是头指针和头结点还在
int ListEmpty(LinkList L) //空表返回1,否则返回0
{
if(L->next != NULL)
return 0;
else
return 1;
}
6.销毁
//从头指针开始,依次释放所有结点
Status DestroyList(LinkList &L)
{
LNode *p = NULL;
while(L != NULL)
{
p = L;
L = L->next;
delete p;
}
return OK;
}
7.清空链表(链表存在但是没有元素)
//将L重置为空表
Status ClearList(LinkList &L)
{
LNode *p=NULL, *q=NULL;
p = L->next;
while(p!=NULL) //没到表尾
{
q = p->next;
delete p;
p = q;
}
L->next = NULL; //头结点指针域为空
return OK;
}
8.求表长
int ListLength_L(LinkList L)
{
LinkList p = L->next; //p指向第一个结点
int index = 0;
while(p != NULL) //遍历统计结点个数
{
index++;
p = p->next;
}
return index;
}
9.获取元素(取第i个元素的值)
//获取线性表L中的某个元素的内容,通过变量e返回
Status GetElem_L(LinkList L, int i, ElemType &e)
{
LNode *p = L->next;
int j = 1;
while(p && j<i)
{
p = p->next;
++j;
}
if(!p || j>i) //第i个元素不存在
return ERROR;
e = p->data;
return OK;
}
10.按值查找
时间复杂度:O(n)
10.1根据指定数据获取该数据所在的位置
//return: 成功返回e元素的地址,失败返回NULL;
LNode *LocateElem(LinkList L, ElemType e)
{
LNode *p = L->next;
while(p && p->data != e){
p = p->next;
}
return p;
}
10.2根据指定数据获取该数据的位置序号
//return: 成功返回e元素的位置序号,失败返回0;
LNode *LocateElem(LinkList L, ElemType e)
{
LNode *p = L->next;
int j = 1;
while(p && p->data != e){
p = p->next;
j++;
}
if(p != NULL)
return j;
else
return 0;
}
11.插入
//在第i个结点前插入值为e的新结点
Status ListInsert_L(LinkList &L, int i, ElemType e)
{
LNode *p = L;
int j = 0;
while(p && j<i-1)//寻找第i-1个结点
{
p = p->next;
++j;
}
if(!p || j>i-1) //非法判断
return ERROR;
s = new LNode; //生成新结点
s->data = e;
s->next = p->next; //将新结点插入到L中
p->next = s;
return OK;
}
12.删除
//将L中第i个数据元素删除
Status ListDelete_L(LinkList &L, int i, ElemType &e)
{
LNode *p = L;
int j = 0;
while(p->next && j<i-1){ //找到第i个结点,p指向其前驱
p=p->next;
++j;
}
if(!(p->next) || j>i-1)
return ERROR;
q=p->next; //临时保存被删结点的地址用于释放
p->next = q->next;
e=q->data; //保存删除结点的数据域
delete q;
return OK;
}
13.建立单链表
13.1头插法
//头插法建立一个链表,直接实用性不大 ,时间复杂度: O(n)
void CreateList_H(LinkList &L, int n)
{
L = new LNode;
L->next = NULL;
for(int i=n; i>0; --i)
{
p = new LNode;
cin >> p->data; //手动输入
p->next = L->next;
L->next = p;
}
}
13.2尾插法
//正位序输入n个元素的值,建立带头结点的单链表L,时间复杂度:O(n),直接实用性不大
void CreateList_R(LinkList &L, int n)
{
L = new LNode;
L->next = NULL;
LNode *r = L;
for(int i=0; i<n; ++i){
p = new LNode;
cin >> p->data;
p->next = NULL;
r->next = p;
r=p;
}
}
=========================================================================
视频:戳这里_B站大学
推荐相关文章:数据结构(C++)学习篇(二):线性表(顺序表示和实现)