用链接存储方式存储的线性表称为链表。链表主要有三种实现方式:单链表,循环链表和双向链表。
单链表的定义:一个单链表有数据域和指针域组成。 其中数据域存放该节点的数据域的值,指针域next存放该节点的后继结点的地址信息。
data | next |
一 单链表的顺序存储结构:
链表的插入操作: ListInsert (*L, i, e) , 即在线性表的第i个位置插入新元素e;
插入算法思路:
1. 如果插入位置不合理,跑出异常(线性表的长度大于Maxsize, 要插入的位置小于1, 或者要插入的位置大于链表长度);
2. 从最后一个元素开始向前遍历到第i个位置,分别将它们向后移动一个位置;
3. 将要插入的元素填入到位置i之前;
4. 线性表长度加1。
void ListInsert(Sqlist *L, int i, ElemType e)
{
int k = 0;
if (i>L->length+1 || i<1 || L->length == MaxSize )
{
return ERROR; //i 不在范围内,或者是顺序表已经满了,线性表下标是从1开始
}
if (i <= L->length) //若插入数据位置不在表尾
{
for (k = L->length-1; k>=i-1; k--)
{
L->data[k+1] = L->data[k];
}
}
L->data[i-1] = e;
L->length++;
}
单链表的删除操作:
void ListDelete (Sqlist *L, int i, ElemType *e)
{
int k = 0;
if (i>L->length+1 || i<1 || L->length == MaxSize )
{
return ERROR; //i 不在范围内,或者是顺序表已经满了
}
if (i < L->length) //若插入数据位置不在表尾
{
for (k = i; k<L->length-1; k++)
{
L->data[k-1] = L->data[k];
}
}
e = L->data[i-1];
L->length--;
}
二 单链表的链式存储结构:
单链表的查找操作:
void FindElem (LinkList L, int i, ElemType *e)
{
int j;
LinkList p;
p = L->next;
j = 1;
while (p && j<i)
{
p = p->next;
j++;
}
if (!p || j>i)
{
printf ("Opps! Error!\n");
}
*e = p->data;
}
单链表的插入操作:
void LinkInsertElem (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)
{
printf ("Opps! Error!\n");
}
s = (LinkList)malloc(sizeof(Node));
s->data = e;
s->next = p->next;
p->next = s;
}
单链表的删除操作:
void LinkDelete(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)
{
printf ("Opps! Error!\n");
}
q = p->next;
p->next = q->next;
e = q->data;
free(q);
}