目录
线性表的链式存储结构的特点是用一组任意的存储单元存储线性表的数据元素(这组存储单元可连续、也可不连续)。
链表优点 | 链表缺点 |
1、不要求占用连续的存储空间,可动态进行分配。 2、插入和删除操作效率高,不需要移动元素。 | 1、不能随意访问任一元素。 2、为了表示元素间的逻辑关系,需增加额外的空间。 |
结点中只含一个指针域的链表,叫单链表。单链表中,除头尾结点外,各结点的关系都是只有一个前驱和一个后继。
//-------------------------线性表的单链表存储结构-------------------------//
typedef structLNode{
ElemType data; //结点的数据域
struct LNode *next; //结点的指针域
}LNode, *LinkList; //LNode:结构体类型;*LinkList:指向LNode结构体类型的指针
a1表示首元结点。 Head是LinkList型的变量,Head为单链表的头指针,指向表中的第一个结点。 在单链表的第一个结点之前附设一个结点,称为头结点。头结点的数据域可以不存储任何信息,也可以存储如线性表的长度等类的附加信息,头结点的指针域存储指向第一个结点的指针(即第一个元素结点的存储位置)。 若线性表为空表,则头结点的指针域为“空”。 |
1、单链表初始化
int InitList(LinkList *head)
{
*head = (LNode *)malloc(sizeof(LNode)); //申请一个结点
if(head == NULL)
return -1; //申请内存空间失败
head->next = NULL; //指针域置空
return head;
}
2、建立单链表
将线性表n个元素存放在一个单链表中,head为头指针。建立单链表的方法不止一种,下面分别介绍。
(1)、尾插法建立单链表
通过不断在单链表的尾部插入结点的方法建立单链表。
LinkList CreateList_Rear(LinkList *head, ElemType a[], int n) //尾插法
{
*head = (LNode *)malloc(sizeof(LNode));
head->next = NULL;
LNode *Rear; //定义Rear始终指向尾部结点,开始时指向头结点
Rear = head;
for(int i=0; i<n; i++)
{
LNode *p = (LNode *)malloc(sizeof(LNode)); //申请新的结点
p->data = a[i];
Rear->next = p;
Rear = p; //更新尾部指针
}
Rear->next = NULL;
return head;
}
(2)、头插法建立单链表
从一个空表开始,通过不断在单链表头部插入结点的方法来建立链表。
LinkList CreateList_Front(LinkList *head, ElemType a[], int n) //头插法
{
*head = (LNode *)malloc(sizeof(LNode)); //申请头结点空间
head->next = NULL;
LNode *Front;
Front = head->next;
for(int i=n-1; i>=0; i--)
{
LNode *p = (LNode *)malloc(sizeof(LNode)); //申请新的结点
p->data = a[i];
p->next = Front;
head->next = p;
Front = p;
}
return 0;
}
3、单链表的插入运算
在链表指定位置插入给定的值
在链表的第 i 个位置之前插入元素 e
int ListInsert_befor(LinkList *head, int i, ElemType e)
{
if(i < 1)
return -1; //不合法
int temp = 1;
LNode *p = (*head)->next; //head为头指针,p为头结点,p->next为首元结点
while(temp!=i && p->next!=NULL)
{
p = p->next;
temp++;
}
if(p->next == NULL)
return -1;
LNode *s = (LNode *)malloc(sizeof(LNode));
if(s == NULL)
return -1; //申请失败
s->data = e;
s->next = p->next;
p->next = s;
return 0;
}
4、单链表的删除运算
(1)、在单链表中删除值为e的元素
int ListDelete(LinkList *head, ElemType e)
{
LNode *p = (*head)->next; //head为头指针,p为头结点,p->next为首元结点
while(p->next->data != e)
{
p = p->next;
}
if(p->next == NULL)
return -1;
p->next = p->next->next; //删除
return 0;
}
(2)、删除单链表第i个元素,用e返回其值
int ListDelete(LinkList *head, int i, ElemType *e)
{
if(i < 1)
return -1; //不合法
LNode *p = (*head)->next; //head为头指针,p为头结点,p->next为首元结点
int temp = 1;
while(temp!=i && p->next!=NULL)
{
p = p->next;
temp++;
}
if(p->next == NULL)
return -1;
*e = p->next->data;
p->next = p->next->next;
return 0;
}