单链表
单链表的定义
线性表的链式存储又称单链表,它是指通过一组任意的存储单元来存储线性表中的数据元素。为了建立数据元素之间的线性关系,对每个链表结点,除了存放元素数据自身的信息外,还需要存放一个指向后继元素的指针。单链表的结构就是data+next,其中data为数据域,next为指针域,存放其后继结点的地址。
单链表上基本操作的实现
单链表的声明
typedef struct LNode
{
ElemType data; //存放元素值
struct LNode * next; //指向后继结点
}LinkNode; //单链表结点类型
建立单链表
头插法
void CreateListF(LinkNode *&L,ElemType a[],int n)
{
LinkNode *s;
L = (LinkNode *)malloc(sizeof(LinkNode));
L->next = NULL; //创建头结点,其next域置为NULL
for (int i=0 ; i<n ; i++){ //循环建立数据结点s
s = (LinkNode *)malloc(sizeof(LinkNode));
s->data = a[i]; //创建数据结点s
s->next = L->next; //将结点s插入到原首结点之前,头结点之后
L->next = s;
}
}
尾插法
void CreateListR(LinkNode *&L,ElemType a[],int n)
{
LinkNode *s,*r;
L = (LinkNode *)malloc(sizeof(LinkNode)); //创建头结点
r = L; //r始终指向尾结点,初始时指向头结点
for (int i=0 ; i<n ; i++){ //循环建立数据结点s
s = (LinkNode *)malloc(sizeof(LinkNode));
s->data = a[i]; //创建数据结点s
r->next = s; //将结点s插入到结点r之后
r = s;
}
r->next = NULL; //尾结点的next域置为NULL
}
初始化
void InitList(LinkNode *&L)
{
L = (LinkNode *)malloc(sizeof(LinkNode));
L->next = NULL;
}
销毁线性表
void DistroyList(LinkNode *&L)
{
LinkNode *pre = L , p = L->next; //pre指向结点p的前驱结点
while(p != NULL){ //扫描单链表L
free(pre); //释放pre结点
pre = p; //pre、p同步后移一个结点
p = p->next;
}
free(pre); //循环结束时p为NULL,pre指向尾结点,释放它
}
判断线性表是否为空表
bool ListEmpty(LinkNode *L)
{
return (L->next == NULL);
}
求线性表的长度
int ListLength(LinkNode *L)
{
int n = 0;
LinkNode *p = L;
while (p->next != NULL){
n++;
p = p->next;
}
return n;
}
输出线性表
void DispList(LinkNode *L)
{
LinkNode *p = L->next; //p指向首结点
while(p != NULL){ //p不为NULL时,输出p结点的data域
printf("%d", p->data);
p = p->next;
}
printf("\n");
}
求线性表中的某个数据元素值
bool GetElem(LinkNode *L,int i,ElemType &e)
{
int j = 0;
LinkNode *p = L; //p指向首结点,j置为0,即头结点的序号为0
if(i <= 0) return false; //i错误返回假
while(j<i && p!=NULL){ //找到第i个结点p
i++;
p = p->next;
}
if(p == NULL) return false; //不存在第i个数据结点,返回false
else{
e = p->next; //存在第i个数据结点结点,返回true
return true;
}
}
按元素值查找
int LocateElem(LinkNode *L,ElemType e)
{
int i = 1;
LinkNode *p = L->next; //p指向首结点,i置为1,即首届点的的序号为1
while(p!=NULL && p->data!=e){ // 查找data值为e的结点,其序号为i
p = p->next;
i++;
}
if(p == NULL) return(0); //不存在,返回0
else return(i); //存在,返回1
}
插入数据元素
bool ListInsert(LinkNode *&L,int i,ElemType e)
{
int j = 0;
LinkNode *p = L,*s; //p指向头结点,j置为0,即头结点序号为0
if(i <= 0) return false; //i错误时返回false
while(j<i-1 && p!=NULL){ //查找第i-1个结点p
j++;
p = p->next;
}
if(p == NULL) return false; //未找到第i-1个结点,返回false
else{ //找到第i-1个结点p,插入新结点并返回true
s = (LinkNode *)malloc(sizeof(LinkNode));
s->data = e; //建立新结点s,其data域置为e
s->next = p->next; //结点s插入到p之后
p->next = s;
return true;
}
}
删除数据元素
bool ListDelete(LinkNode *&L,int i,ElemType e)
{
int j = 0;
LinkNode *p = L,*q;
if(i <= 0) return false;
while(j<i-1 && p!=NULL){
j++;
p = p->next;
}
if(p == NULL) return false;
else{
q = p->next;
if(q == NULL) return false;
e = q->data;
p->next = q->next;
free(q);
return true;
}
}