链式存储结构:
链式存储结构的存储结点包括数据域和指针域
头结点和头指针的区别:
头指针为指向第一个结点的指针,是链表的必要元素
头结点放在第一个元素的结点之前,不一定是链表的必须要素
单链表的读取
#define ERROR 0
#define OK 1
status GetElem(LinkList L, int i, ElemType *e)
{
int j;
LinkList p;
p = L->next;
j = 1;
while (p&&i < j)
{
p = p->next;
++j;
}
if (!p || j > i)
return ERROR;
e = p->data;
return OK;
}
链表插入
#define ERROR 0
#define OK 1
status ListInsert(LinkList *L, int i, ElemType e)
{
int j;
LinkList p, s;
p = *L;
j = 1;
while (p&&j < i)
{
p = p->next;
++j;
}
if (!p || j > i)
{
return ERROR;
}
s = (LinkList)malloc(sizeof(Node));
s->data = e;
s->next = p->next;
p->next = s;
return OK;
}
链表删除
status ListDelete(LinkList *L, int i, ElemType *e)
{
int j;
LinkList p, q;
p = *L;
j = 1;
while (p->next&&j < i)
{
p = p->next;
++j;
}
if (!p->next || j > i)
{
return ERROR;
}
q = p->next;
p - next = q->next;
*e = q->data;
free(q);//此处记得释放内存
return OK;
}
插入和删除算法都分为两个部分
第一部分:遍历查找第i个结点
第二部分:插入和删除结点
单链表的整表创建
算法思路:
(1) 声明指针p和计数器变量i
(2) 初始化空链表L
(3) 让L的头结点指向NULL,即创建一个带头结点的单链表
(4) 循环
生成一个新节点赋值给p
随机生成一数字赋值给p的数据域p->data
将p插入到头结点与前一新节点之间
头插法
void CreateListHead(LinkList *L, int n)
{
//创建一个p,一个L,p代表当前结点,L代表链表,L不用创建,传入
LinkList p;
int i;
srand(time(0));
*L = (LinkList)malloc(sizeof(Node));
(*L)->next = NULL;
for (int i = 0; i < n; i++)
{
p= (LinkList)malloc(sizeof(Node));
p->data = rand() % 100 + 1;
p->next = (*L)->next;
(*L)->next = p;
}
}
尾插法:
void LinkListTail(LinkList *L, int n)
{
LinkList p,r;
int i;
srand(time(0));
*L = (LinkList)malloc(sizeof(Node));
r = *L;
for (int i = 0; i < n; i++)
{
p = (LinkList)malloc(sizeof(Node));
P->data = rand() % 100 + 1;
r->next = p;
r = p;
}
r->next = NULL;
}
整链表删除
算法思路:
(1) 声明结点p,q;
(2) 将第一个结点赋值给p
(3) 循环:
将下一结点赋值给p
释放p
将q赋值给p
status ClearList(LinkList *L)
{
LinkList p, q;
p = (*L)->next;
while (p)
{
q = p->next;
free(p);
p = q;
}
(*L)->next = NULL;
return OK;
}