2.3.1 线性表链式存储结构的定义
1、结点:由数据域和指针域组成,数据域用来存储数据元素的信息,指针域用于存储数据元素之间的逻辑关系。
2、链表:n个结点链结成一个链表。
数据域 | 指针域 |
3、单链表:结点只有一个指针域的链表。
4、双链表:结点有两个指针域的链表。
5、循环链表:首尾相接的链表。
6、不带头结点的单链表
7、带头结点的单链表
8、头指针:指向链表中第一个结点的存储位置的指针
9、头结点:是在单链表中的第一个结点前附设的一个结点
10、头结点的好处:为了操作的统一和方便而设立,链表第一个元素的操作和其它位置保持一致。
2.3.2 线性表链式存储结构的实现
1、数据类型的定义
#define OK 0
#define ERROR 1
typedef int ElemType;
typedef int Status;
typedef struct LNode{
ElemType data;
struct LNode *next;
}LNode, *LinkList;
2、线性表的初始化
Status LinkList_Init(LinkList *L)
{
*L = (LinkList)malloc(sizeof(LNode));
if (*L == NULL)
return ERROR;
(*L)->next = NULL;
return OK;
}
3、判断线性表是否为空
Status LinkList_IsEmpty(LinkList *L)
{
if ((*L)->next == NULL)
return OK;
else
return ERROR;
}
4、获取线性表的表长
int LinkList_GetLength(LinkList *L)
{
int length = 0;
LNode* p = *L;
while(p->next != NULL)
{
length++;
p = p->next;
}
return length;
}
5、销毁线性表
Status LinkList_Destory(LinkList *L)
{
LNode *p;
if (*L != NULL)
{
p = *L;
*L = p->next;
free(p);
}
return OK;
}
6、清空线性表
Status LinkList_Clear(LinkList *L)
{
LNode *p, *q;
p = (*L)->next;
while (p != NULL)
{
q = p;
p = p->next;
free(q);
}
(*L)->next = NULL;
return OK;
}
7、获取线性表第i个数据元素的值
Status LinkList_GetElem(LinkList *L, int i, ElemType *e)
{
LNode *p = (*L)->next;
int j = 1;
while (p && j < i)
{
p = p->next;
j++;
}
if (p == NULL || j > i)
return ERROR;
e = p->data;
return OK;
}
8、按值查找返回线性表数据元素的地址
LNode* LinkList_LocateElem1(LinkList *L, ElemType e)
{
LNode *p = (*L)->next;
while (p && p->data != e)
p = p->next;
return p;
}
9、按值查找返回数据元素的位置序号
int LinkList_LocateElem2(LinkList *L, ElemType e)
{
LNode *p = (*L)->next;
int j = 1;
while (p && p->data != e)
{
j++;
p = p->next;
}
if (p)
return j;
else
return 0;
}
10、在线性表第i个位置插入数据元素
Status LinkList_InsertElem(LinkList *L, int i, ElemType e)
{
LNode *p = (*L);
int j = 0;
while (p && j < i-1)
{
p = p->next;
j++;
}
if (p == NULL || j > i-1)
return ERROR;
LNode *s = (LinkList)malloc(sizeof(LNode));
s->data = e;
s->next = p->next;
p->next = s;
return OK;
}
11、删除线性表中的第i个数据元素
Status LinkList_DeleteElem(LinkList L, int i, ElemType *e)
{
LNode *p, q;
p = (*L);
int j = 0;
while (p && j < i-1)
{
p = p->next;
j++;
}
if (p == NULL || j > i-1)
return ERROR;
q = p->next;
p->next = q.next;
free(q);
return OK;
}
12、头插法建立线性表
void LinkList_Create_Head(LinkList *L, int n)
{
LNode *p;
for (int i = n; i > 0; --i)
{
p = (LinkList)malloc(sizeof(LNode));
scanf("%d", &(p->data));
p->next = (*L)->next;
(*L)->next = p;
}
}
13、尾插法建立线性表
void LinkList_Create_Tail(LinkList *L, int n)
{
LNode *r = (*L);
LNode *p;
while (r->next != NULL)
r = r->next;
for (int i = 0; i < n; i++)
{
p = (LinkList)malloc(sizeof(LNode));
p->next = NULL;
r->next = p;
r = p;
}
}