因为是先学了链栈和链队列再学的单链表,大体操作可以触类旁通,但有些细节还要熟练一下。
代码包含
初始化 判空
在单链表的第i个位置插入e
删除第i个结点,并用e返回该结点的值
删除单链表中所有值为x的元素
销毁 6个操作,具体细节以备注形式写出
#include <stdio.h>
#include <stdlib.h>
typedef struct LNode{
ElemType data; //ElemType表示所有可能的类型,无特殊说明默认int型,data表示数据域
struct LNode *next; //指针域
}LNode,*LinkList;
//初始化
Status InitList_L(LinkList &L){ //这里的&是C++里的形参符号,在函数内部对形参的操作都等于直
L=(LNode*)malloc(sizeof(LNode)); //接操作原变量
if(NULL==L)return OVERFLOW;
L->next=NULL; //初始化时,头结点的指针域即首元结点为NULL
}
//判空
Status ListEmpty_L(LinkList L){
if(NULL==L->next)return TRUE;
return FALSE;
}
//在单链表的第i个位置插入e
Status Insert_L(LinkList &L,int i,ElemType e){
LNode *p=L,*q;
int j=0;
if(NULL==L||i<=0||NULL==L->next)return ERROR;
q=(LNode*)malloc(sizeof(LNode));
if(q!=NULL){ //判断是否分配成功
q->data=e;
q->next=NULL; //易漏
}
for(j=0;j<i-1;j++){ //找到第i-1结点,而不是第i个,因为在中间插入需要用到第i-1个结点
p=p->next; //当j=i-1时,p对应为第i-1个结点
if(NULL==p)return ERROR; //可能还没到第i-1个位置p就为NULL,这种情况无法满足插入条件
}
q->next=p->next;
p->next=q;
return OK;
}
//删除第i个结点,并用e返回该结点的值
Status Delete_L(LinkList &L,int i,ElemType &e){
LNode *p=L,*q;
if(NULL==L||i<=0||NULL==L->next)return ERROR;
int j;
for(j=0;j<i-1;j++){
p=p->next;
if(NULL==p->next)return ERROR; //判断下一个位置是否为空,开始时,p=p->next=L->next开头已
} //判断,故直接判断p->next,当j=i-1时,判断第i个结点是否为空
q=p->next;
p->next=q->next;
e=q->data;
free(q);
return e;
}
//删除单链表中所有值为x的元素
Status DeleteX_L(LinkList &L,ElemType x){
LNode *p=L,*q;
if(NULL==L||NULL==L->next)return ERROR;
int i=0;
while(p->next!=NULL){ //判断下一个结点是否为空
if(p->next->data==x){ //判断下一个结点的数据域是否为x
q=p->next;
p->next=q->next; //之前的判断下一个结点都是为了方便删除操作
free(q);
i++;
}
else p=p->next; //易漏else
}
return i;
}
//销毁单链表
Status DestroyList_L(LinkList &L){
if(NULL==L)return ERROR;
LNode *p=L->next;
while(p!=NULL){
L->next=p->next;
free(p);
p=L->next;
}
L=NULL; //头结点也要置空,缺少这一步就成了清空操作
return OK;
}