链式表相关定义
- 与线性表比较
优点 | 缺点 | |
---|---|---|
线性表 | 可通过下标随机存取某元素 | 插入删除时需移动大量元素 |
链式表 | 插入删除时不需移动大量元素 | 不可随机存取 |
- 定义
节点:储存本身信息+储存直接后继的位置,两部分构成
数据域:储存本身信息的域
指针域:储存直接后继位置的域
- 头结点
有时,我们会在单链表第一个节点前附设一个节点,称为头结点。头结点的数据可不储存任何信息,也可储存链表长度等信息。
在下边链式表的表示中,均默认存在头结点。
链式表的表示与相关操作的实现
- 链式表的表示(带头结点)
typedef struct LNode{
ElemType data;//数据域
struct LNode *next;//指针域
}LinkList;
//此结构既表示链式表,又表示链表的头结点
- 相关操作
Status InitLinkList(LinkList *L);
Status InsertElemIntoLinkList(LinkList *L, int i, ElemType e);
ElemType GetElemFromLinkList(LinkList L, int i, ElemType *e);
ElemType GetIndexFromLinkList(LinkList L, int *i, ElemType e);
Status DeleteElemFromLinkList(LinkList *L, int i);
Status IsElemFromLinkList(LinkList L, ElemType e);
Status AppendElemForLinkList(LinkList *L, ElemType e);
int LengthLinkList(LinkList L, int *length);
Status ClearLinkList(LinkList *L);
Status DestroyLinkList(LinkList *L);
Status TraverseLinkList(LinkList L);
- 初始化链式表
Status InitLinkList(LinkList *L){
L=(LinkList*)malloc(sizeof(LinkList));
if(!L){
return OVERFLOW;
}
L->data=0;
L->next=NULL;
return OK;
}//创建一个只有头结点的空链表
- 插入元素
Status InsertElemIntoLinkList(LinkList *L, int i, ElemType e){
if(i<1||!L){
return ERROR;
}
LinkList *pointer;
pointer=L;
for(int count=1;count<i;count++){
pointer=L->next;
if(!pointer){
return ERROR;
}
}//遍历节点,找到第i-1个节点
LinkList *insert=(LinkList*)malloc(sizeof(LinkList));
if(!insert){
return OVERFLOW;
}//创建一个新节点
LinkList *temp=pointer->next;
pointer->next=insert;
insert->next=temp;
insert->data=e;//在第i个节点前插入
return OK;
}
- 删除元素
Status DeleteElemFromLinkList(LinkList *L, int i){
if(i<1||!L){
return ERROR;
}
LinkList *pointer=L;
for(int count=1;count<i;count++){
pointer=pointer->next;
if(!pointer||!pointer->next){
return ERROR;
}
}//遍历节点,找到第i-1个节点
LinkList *temp=pointer->next;
pointer->next=temp->next;
free(temp);//清空第i个节点的储存空间
return OK;
}
- 根据下标得到元素
ElemType GetElemFromLinkList(LinkList L,int i,ElemType *e){
if(i<1||!&L){
return ERROR;
}
LinkList *pointer=L.next;
for(int count=1;count<i;count++){
pointer=L.next;
if(!pointer){
return ERROR;
}
}
*e=pointer->data;
return *e;
}
- 根据元素得到下标
ElemType GetIndexFromLinkList(LinkList L, int *i, ElemType e){
LinkList *pointer=L.next;
int count=1;
while(pointer){
if(pointer->data==e){
*i=count;
return *i;
}
pointer=pointer->next;
count++;
}
return ERROR;
}
比较前四种操作可发现,当函数以链式表L为变量时,pointer指针指向第一个元素;而以链式表指针*L为变量时,pointer指针指向头结点
- 判断元素是否在链式表中
Status IsElemFromLinkList(LinkList L, ElemType e){
LinkList *pointer=L.next;
while(pointer){
if(pointer->data==e){
return OK;
}
pointer=pointer->next;
}
return ERROR;
}
- 在表尾插入一个元素
Status AppendElemForLinkList(LinkList *L, ElemType e){
if(!L){
return ERROR;
}
LinkList *pointer=L;
while(pointer->next){
pointer=pointer->next;
}//遍历到链式表最后一个元素
LinkList *append=(LinkList*)malloc(sizeof(LinkList));
if(!append){
return ERROR;
}
pointer->next=append;
append->data=e;
append->next=NULL;
return OK;
}
- 得到链式表长度
int LengthLinkList(LinkList L, int *length){
int count=0;
LinkList *pointer=L.next;
while(pointer){
count++;
pointer=pointer->next;
}
*length=count;
return *length;
}
- 清空链式表
Status ClearLinkList(LinkList *L){
if(!L){
return ERROR;
}
LinkList *pointer=L->next;
while(pointer){
LinkList *temp=pointer;
pointer=pointer->next;
free(pointer);
}
L->next=NULL;
return OK;
}
保留头结点,则此链式表还可以使用(相当于初始化了一个空链式表)
- 销毁链式表
Status DestroyLinkList(LinkList *L){
if(L){
ClearLinkList(L);
}
free(L);//释放头结点储存空间
L=NULL;
return OK;
}
- 遍历链式表中的元素
Status TraverseLinkList(LinkList L){
LinkList *pointer=L.next;
int count=1;
while(pointer){
printf("The %dth elem is %d",count,pointer->data);
count++;
pointer=pointer->next;
}
return OK;
}
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。