目录
2.5 线性表的链式表示和实现2
1、知识回顾
(1)线性表的链式存储结构
线性表中数据元素(结点)在存储器中的位置是任意的,即逻辑上相邻的数据元素在物理位置上不一定相邻。
(2)结点

(3)链表
n个结点由指针链组成一个链表。链表是顺序存取的。

①单链表:每个结点只有一个指针域。
②双链表:每个结点有两个指针域。
③循环链表:链表结点首尾相接。
2、单链表的定义
带头结点的单链表:


单链表是由表头唯一确定的,因此单链表可以用头指针的名字来命名。若头指针名是L,则把链表称为表L。
3、单链表的存储结构


//单链表的存储结构
typedef struct Lnode{//声明结点的类型和指向结点的指针类型
Elemtype data;//结点的数据域
struct Lnode *next;//结点的指针域
}Lnode, *LinkList;//LinkList为指向结构体Lnode的指针类型
定义链表L:
LinkList L;
定义结点指针p:
LNode *P;
等价于:
LinkList p;
4、例子
例如,存储学生学号、姓名、成绩的单链表结点类型定义如下:
//存储学生学号、姓名、成绩的单链表结点类型定义
typedef struct student{
char num[8];//数据域
char name[8];//数据域
int score;//数据域
struct student *next;//指针域
}Lnode, *LinkList;

为了统一链表的操作,通常这样定义:
//为了统一链表的操作,通常这样定义
typedef struct{
char num[8];//数据域
char name[8];//数据域
int score;//数据域
}ElemType;
typedef struct Lnode{
ElemType data;//数据域
struct Lnode *next;//指针域
}Lnode, *LinkList;
2.5 线性表的链式表示和实现3
1、单链表基本操作的实现
(1)单链表的初始化(算法2.6)(带头结点的单链表)
即构造一个如图的空表。

算法步骤:
①生成新结点作头结点,用头指针L指向头结点。
②将头结点的指针域置空。
算法描述:
//单链表的初始化(算法2.6)(带头结点的单链表)
typedef struct Lnode{
ElemType data;
struct Lnode *next;
}LNode, *LinkList;
Status InitList_L(LinkList &L){
L = new LNode;//或L = (LinkList)malloc(sizeof(LNode));
L->next = NULL;
return OK;
}
(2)补充单链表的几个常用简单算法
【补充算法1】判断链表是否为空。
空表:链表中无元素,称为空链表(头指针和头结点仍然在)。

【算法思路】判断头结点指针域是否为空。
//判断链表是否为空
int ListEmpty(LinkList L){//若L为空表,则返回1,否则返回0
if(L->next){//非空
return 0;
}
else{
return 1;
}
}
2、具体实现
//具体实现
#include <stdio.h>
#include <stdlib.h>
//操作算法中用到的预定义常量和类型
//函数结果状态代码
#define TRUE 1
#define FALSE 0
#define OK 1
#define ERROR 0
#define INFEASIBLE -1
#define OVERFLOW -2
#define MaxSize 100
//Status是函数的类型,其值是函数结果状态代码
typedef int Status;
typedef int ElemType;
//单链表的初始化(算法2.6)(带头结点的单链表)
typedef struct Lnode{
ElemType data;
struct Lnode *next;
}LNode, *LinkList;
Status InitList_L(LinkList &L){
L = new LNode;//或L = (LinkList)malloc(sizeof(LNode));
L->next = NULL;
return OK;
}
//判断链表是否为空
int ListEmpty(LinkList L){//若L为空表,则返回1,否则返回0
if(L->next){//非空
return 0;
}
else{
return 1;
}
}
int main(){
LinkList L;
int choice, ans;
while(1){
printf("线性表的链式表示和实现3(菜单):\n");
printf("1、单链表的初始化 2、链表是否为空\n");
printf("请输入菜单序号:\n");
scanf("%d", &choice);
switch(choice){
case 1:
ans = InitList_L(L);
if(ans){
printf("初始化成功\n");
}
else{
printf("初始化失败\n");
}
break;
case 2:
ans = ListEmpty(L);
if(ans){
printf("链表为空\n");
}
else{
printf("链表不为空\n");
}
break;
}
}
return 0;
}
2.5 线性表的链式表示和实现4
1、单链表基本操作的实现
(1)补充单链表的几个常用简单算法
【补充算法2】单链表的销毁:链表销毁后不存在。
【算法思路】从头指针开始,依次释放所有结点。

【算法】销毁单链表L。
//单链表的销毁:链表销毁后不存在
Status DestroyList_L(LinkList &L){//销毁单链表L
Lnode *p;//或LinkList p;
while(L){
p = L;
L = L->next;
delete p;
}
return OK;
}
2、具体实现
//具体实现
#include <stdio.h>
#include <stdlib.h>
//操作算法中用到的预定义常量和类型
//函数结果状态代码
#define TRUE 1
#define FALSE 0
#define OK 1
#define ERROR 0
#define INFEASIBLE -1
#define OVERFLOW -2
#define MaxSize 100
//Status是函数的类型,其值是函数结果状态代码
typedef int Status;
typedef int ElemType;
//单链表的初始化(算法2.6)(带头结点的单链表)
typedef struct Lnode{
ElemType data;
struct Lnode *next;
}LNode, *LinkList;
Status InitList_L(LinkList &L){
L = new LNode;//或L = (LinkList)malloc(sizeof(LNode));
L->next = NULL;
return OK;
}
//单链表的销毁:链表销毁后不存在
Status DestroyList_L(LinkList &L){//销毁单链表L
Lnode *p;//或LinkList p;
while(L){
p = L;
L = L->next;
delete p;
}
return OK;
}
int main(){
LinkList L;
int choice, ans;
while(1){
printf("线性表的链式表示和实现4(菜单):\n");
printf("1、单链表的初始化 2、单链表的销毁\n");
printf("请输入菜单序号:\n");
scanf("%d", &choice);
switch(choice){
case 1:
ans = InitList_L(L);
if(ans){
printf("初始化成功\n");
}
else{
printf("初始化失败\n");
}
break;
case 2:
ans = DestroyList_L(L);
if(ans){
printf("单链表已销毁\n");
}
else{
printf("单链表销毁失败\n");
}
break;
}
}
return 0;
}
这篇博客详细介绍了线性表的链式存储结构,包括结点概念、单链表定义及其存储结构。重点讨论了带头结点的单链表初始化算法,以及如何判断链表是否为空。此外,还补充了单链表的销毁算法,探讨了释放链表所有结点的过程。
799

被折叠的 条评论
为什么被折叠?



