*因借用C++引用语法,主体代码以C++为主,提及C语言
目录
基础知识
单链表结构:数据元素(data)、指向其后继的指针(next)
头指针【必需元素】:标识一个单列表,指向链表的第一个节点(有头结点即为头结点)
头结点【非必需元素】:在单链表第一个节点之前附加的一个节点,不存储数据,方便操作设立。
单链表的定义
定义函数
typedef struct LNode
{
ElemType data;//数据域(该节点内存储的数据)
struct LNode *next;//指针域(该节点内存储的指向下一节点的指针)
}LNode,*LinkList;//单链表的类型定义(顺序表的别名)
实现函数
L=(LinkList)malloc(sizeof(LNode));//申请一个带头结点链表的空间
*若线性表为空表,则头指针的指针域为“空”。
单链表的基本操作
头插法建立单链表
图解
代码实现
LinkList CreatList1(LinkList &L)//头插法新建链表
{
LNode *s;int x;
L=(LinkList)malloc(sizeof(LNode));//申请带头结点的链表空间L
L->next=NULL;//初始化为空链表
scanf("%d",&x);//从标准输入读取数据
while(x!=9999)//输入9999代表结束
{
s=(LNode*)malloc(sizeof(LNode));//申请一个新空间给新结点指针s
s->data=x;//将读取值x赋给新结点指针s所指向的结点
s->next=L->next;//1.让s指向的结点(ai)的指针域等于原L所指向结点(头结点)的指针域 (a1)
L->next=s;//2.让s成为第一个储存设定数据的元素 (即L指向的元素的指针域为s)
scanf("%d",&x);//输入下一个元素
}
return L;//完成建表
}
CreatList1(L);
尾插法新建链表
图解
代码实现
LinkList CreatList2(LinkList &L)//尾插法新建链表
{
int x;
L=(LinkList)malloc(sizeof(LNode));//申请带头结点的链表空间L
LNode* s, * r = L;//LinkList s,r=L;r为链表表尾结点
scanf("%d",&x);//从标准输入读取数据
while(x!=9999)//输入9999代表结束
{
s=(LNode*)malloc(sizeof(LNode));//申请一个新空间给新结点指针s
s->data=x;//将读取值x赋给结点指针s所指向的结点
r->next=s;//让原尾部结点的指针域指向新尾部结点
r=s;//让指针r指向新的尾部结点
scanf("%d",&x);//输入下一个元素
}
r->next=NULL;//建表完成后需将尾结点的next指针赋值为NULL
return L;//完成建表
}
CreatList2(L);
按序号查找结点值
函数定义
LNode *GetElem(LinkList L,int i)//按序号查找结点值
{
int j=1;//定义遍历时计数值
LNode *p=L->next;//定义p为头结点
if(i==0)//若i等于0,则返回头结点
return L;
if(i<1)//若i无效,则返回NULL
return NULL;
while(p&&j<i)//从1开始遍历,查找第i个结点
{
p=p->next;//遍历
j++;//计数++
}
return p;//返回查找到的指针
}
函数实现
search=GetElem(L,i);//查找表L中序号为i的值
if(search!=NULL)//查找成功
{
printf("按序号查找成功\n");
printf("%d\n",search->data);//输出表L中序号为i的值
}
按值查找
函数定义
LNode *LocateElem(LinkList L,ElemType e)//按值查找
{
LNode *p=L->next;//定义p为头结点
while(p!=NULL&&p->data!=e)//从1开始遍历数据域为e的结点
p=p->next;//遍历
return p;//返回查找到的指针,若未找到,返回NULL
}
函数实现
search=LocateElem(L,e);//查找表中是否有e,有则打印输出
if(search!=NULL)//查找成功
{
printf("按值查找成功\n");
printf("%d\n",search->data); //输出e
}
新结点插入第i个位置
图解
代码
bool ListFrontInsert(LinkList L,int i,ElemType e)//在判断插入是否合法后,实现插入操作
//L为被插入顺序表,i代表插入的位置(从1开始计数),e为要插入的元素
{
LinkList p=GetElem(L,i-1);//查找插入位置的前驱结点
if(NULL==p)//判断插入位置是否合法
{
return false;//如果不合法,返回错误
}
LinkList s=(LNode*)malloc(sizeof(LNode));//为新插入的结点s申请空间
s->data=e;//将读取值e赋给新结点指针s所指向的结点
s->next=p->next;//1.让s指向的结点(x)的指针域等于原p所指向结点(a)的指针域
p->next=s;//2.让p指向的元素的指针域为s
return true;//插入合法,返回正确
}
ListFrontInsert(L,i,e);//在表L中i位置插入e元素
删除第i个结点
图解
代码
bool ListDelete(LinkList L,int i)//在判断插入是否合法后,实现删除操作
{
LinkList p=GetElem(L,i-1);//查找删除位置的前驱结点
if(NULL==p)//判断删除位置是否合法
{
return false;//如果不合法,返回错误
}
LinkList q;
q=p->next;//定义q指向被删除元素
p->next=q->next;//使p所指向结点指针域等于原q所指向结点指针域
free(q);//释放被删除结点指针的空间
return true;//删除合法,返回正确
}
ListDelete(L,i);//删除表L中第i个结点
打印链表中每个结点的值
void PrintList(LinkList L)//打印顺序表L
{
L=L->next;//使指针L指向第一个元素
while(L!=NULL)//检查L是否合法
{
printf("%3d",L->data);//以每个元素三个空格大小输出表中数据
L=L->next;//指向下一个结点
}
printf("\n");
}
PrintList(L);