此代码不可运行,含伪代码。
一、 定义数据域
typedef struct{
char num[8];
char name[8];
int score;
}ElemType;
二、 定义一个链表
typedef struct LNode{
ElemType data; //链表中结点的数据域
struct Lnode *next; //为指向下一个结点的指针域,并且所指向的也是Lnode型的数据
}LNode,*LinkList;
//LinkList为指向结构体Lnode的指针类型,可定义链表L: LinkList p;等价于 LNode *p;
三、建立一个空表
Status InitList_L(LinkList &L){
L = new LNode; //生成新结点作为头结点,用头指针L指向头结点
// 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;
}
五、销毁链表
Status DestroyList_L(LinkList &L){ //销毁单链表L
Lnode *p;
// LinkList p;
while(L){ //判断L指向的后一个结点是否为空
p = L;
L = L->next;
delete p; //等同于free(p);
}
return OK;
}
六、清除链表的内容,但保留链表的结构
Status ClearList(LinkList &L){ //将L重置为空表
Lnode *p,*q; //或 LinkList p,q;
p = L->next; //这指向的还只是头结点,并不是首元结点
while(p){ //判断下一结点是否为空
q = p->next;
delete p; //等同于free(p); 只是将p的内存给释放了
p = q;
}
L->next = NULL; //令头结点指针域为空
return OK;
}
七、计算链表的长度
int ListLength_L(LinkList L){ //返回L中数据元素的个数
LinkList p; //Lnode *p;
p = L->next;//L为头结点,L->next为L的指针域,所指向的为首元结点的地址。所以p指向的是第一个结点即首元结点。
int i=0;
while(p){ //遍历单链表,统计结点数
i++;
p = p->next; //p指向下一结点
}
return i;
}
八、根据指定位置i,取链表中对应的值e
Status GetElem_L(LinkList L,int i,ElemType &e){ //取值。获取线性表L中的某个数据元素的内容,通过变量e返回
p = L->next; //初始化,让p指向首元结点
int j=1;
while(p && j<i){ //向后扫描,直到p指向的第i个元素 或 p为空
p = p->next;
++j;
}
if(!p || j>i) //若第i个元素不存在
return ERROR;
e = p->data; //取第i个元素
return OK;
}
九、根据给出的e值,返回链表中对应的地址
Lnode *LocateElem_L(LinkList L,ElemType e){ //在线性表L中查找值为e的数据元素
//若找到,则返回L中值为e的数据元素的地址,查找失败则返回NULL。
p = L->next;
while(p && p->data!=e) //p不为空,且没有找到e值
p = p->next; //指向下一个
return p;
}
十、根据给出的e值,返回链表L中该值的位置序号
int LocateElem_L1(LinkList L,ElemType e){ //在线性表L中查找值为e的数据元素的位置序号
//返回L中值为e的数据元素的位置序号
p = L->next;
int j=1; //从头开始计数
while(p && p->data!=e){
p = p->next;
j++;
}
if(p) //如果p值为空,则返回0,否则返回位置序号
return j;
else
return 0;
}
十一、根据给出的位置i,在链表L中插入元素e
Status ListInsert_L(LinkList &L,int i,ElemType e){ //插入。在L中第i个元素之前插入数据元素e
//插入算法中i的合理取值范围是1~n+1。
p = L; //此处p为头结点开始,以防有人要在第一个元素前插入数据元素e
int j = 0;
while(p && j<i-1){ //寻找第i-1个结点。若退出循环,即j=i-1或者p为空。
p = p->next;
++j;
}
if(!p || j>i-1) //若i大于表长+1 或者小于1,则插入位置非法
return ERROR;
这后面几步为关键步骤!!!
s = new LNode; 先生成新结点s
s->data = e; 再将结点s的数据域置为e
s->next = p->next; 先将第i个结点,放在新结点的后面。即新结点指向第i个结点,作为新结点的后继。
p->next = s; 再将新结点放在,第i-1个结点的后面。即第i-1个结点指向新结点,作为新结点的前驱。
return OK;
}
十二、根据给出的位置i,将其在链表中删除,并将删除的数据保存在变量e中
Status ListDelete_L(LinkList &L,int i,ElemType &e){ //将线性表L中第i个数据元素删除。通过e将删除的变量保存起来
LNode *p; //删除算法中i的合理取值范围是1~n。
p = L;
LNode *q;
int j = 0;
while(p->next && j<i-1){ //寻找第i-1个结点,并让p指向第i-1个结点。查找删除第1~n个位置的元素
p = p->next;
++j;
} //跳出循环后此时,p所指向的是第i-1个结点
if(!(p->next) || j>i-1) //删除位置不合理 。!(p->next)的意思是p的后继结点不存在。
return ERROR;
q = p->next; //注意//此时p->next指向的是第i个结点。q是临时保存被删除结点的地址,以备将其释放
p->next = q->next; //注意//也可以写成p->next = p->next->next; 即改变删除结点的前驱结点的指针域。
e = q->data; //保存删除结点的数据域
delete q; //释放删除结点的空间
return OK;
}
十三、头插法建立单链表,逆序插入,链表中正序存储
头插法:元素插入在链表头部。
void CreateList_Head(LinkList &L,int n){ //头插法建立单链表
L = new LNode;
L->next = NULL; //先建立一个带头结点的单链表
for(i=n;i>0;--i){
p = new LNode; //生成新结点p
scanf(&p->data); //输入元素值
p->next = L->next; 插入到头节点。一开始L->next指向为null,新结点指向null 。之后L->next指向上一个循环的旧结点p
L->next = p; 头结点指向新结点 ,之后指向新的结点p
}
}
十四、尾插法建立单链表,正序插入,链表中正序存储
尾插法:元素插入在链表尾部
void CreateList_R(LinkList &L,int n){ //尾插法。正位序输入n个元素的值,建立带表头节点的单链表L
L = new LNode;
L->next = NULL;
LNode *r;
r = L; //尾指针r指向头结点
for(i=0;i<n;++i){
p = new LNode; //生成新结点p
scanf(&p->data); //输入元素值
p->next = NULL;
r->next = p; //插入到表尾 ,将新结点放在尾结点的后面
r = p; //r指向新的尾结点 。新插入的结点就是现在新的尾结点了
}
}
#include<stdio.h> //单链表的基本操作
//此代码不可运行,含伪代码。
#define TRUE 1
#define FALSE 0
#define OK 1
#define ERROR 0
#define INFEASIBLE -1
#define OVERFLOW -2
#define MAXSIZE 100
typedef int Status;
typedef struct{ //定义数据域
char num[8];
char name[8];
int score;
}ElemType;
typedef struct LNode{
ElemType data; //结点的数据域
struct Lnode *next; //为指向下一个结点的指针域,并且所指向的也是Lnode型的数据
}LNode,*LinkList; //LinkList为指向结构体Lnode的指针类型,可定义链表L: LinkList p;等价于 LNode *p;
Status InitList_L(LinkList &L){
L = new LNode; //生成新结点作为头结点,用头指针L指向头结点
// 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;
}
Status DestroyList_L(LinkList &L){ //销毁单链表L
Lnode *p;
// LinkList p;
while(L){ //判断L指向的后一个结点是否为空
p = L;
L = L->next;
delete p; //等同于free(p);
}
return OK;
}
Status ClearList(LinkList &L){ //将L重置为空表
Lnode *p,*q; //或 LinkList p,q;
p = L->next; //这指向的还只是头结点,并不是首元结点
while(p){ //判断下一结点是否为空
q = p->next;
delete p; //等同于free(p); 只是将p的内存给释放了
p = q;
}
L->next = NULL; //令头结点指针域为空
return OK;
}
int ListLength_L(LinkList L){ //返回L中数据元素的个数
LinkList p; //Lnode *p;
p = L->next;//L为头结点,L->next为L的指针域,所指向的为首元结点的地址。所以p指向的是第一个结点即首元结点。
int i=0;
while(p){ //遍历单链表,统计结点数
i++;
p = p->next; //p指向下一结点
}
return i;
}
Status GetElem_L(LinkList L,int i,ElemType &e){ //取值。获取线性表L中的某个数据元素的内容,通过变量e返回
p = L->next; //初始化,让p指向首元结点
int j=1;
while(p && j<i){ //向后扫描,直到p指向的第i个元素 或 p为空
p = p->next;
++j;
}
if(!p || j>i) //若第i个元素不存在
return ERROR;
e = p->data; //取第i个元素
return OK;
}
Lnode *LocateElem_L(LinkList L,ElemType e){ //在线性表L中查找值为e的数据元素
//若找到,则返回L中值为e的数据元素的地址,查找失败则返回NULL。
p = L->next;
while(p && p->data!=e) //p不为空,且没有找到e值
p = p->next; //指向下一个
return p;
}
int LocateElem_L1(LinkList L,ElemType e){ //在线性表L中查找值为e的数据元素的位置序号
//返回L中值为e的数据元素的位置序号
p = L->next;
int j=1; //从头开始计数
while(p && p->data!=e){
p = p->next;
j++;
}
if(p) //如果p值为空,则返回0,否则返回位置序号
return j;
else
return 0;
}
Status ListInsert_L(LinkList &L,int i,ElemType e){ //插入。在L中第i个元素之前插入数据元素e
//插入算法中i的合理取值范围是1~n+1。
p = L; //此处p为头结点开始,以防有人要在第一个元素前插入数据元素e
int j = 0;
while(p && j<i-1){ //寻找第i-1个结点。若退出循环,即j=i-1或者p为空。
p = p->next;
++j;
}
if(!p || j>i-1) //若i大于表长+1 或者小于1,则插入位置非法
return ERROR;
//这后面几步为关键步骤!!!
s = new LNode; //先生成新结点s
s->data = e; //再将结点s的数据域置为e
s->next = p->next; //先将第i个结点,放在新结点的后面。即新结点指向第i个结点,作为新结点的后继。
p->next = s; //再将新结点放在,第i-1个结点的后面。即第i-1个结点指向新结点,作为新结点的前驱。
return OK;
}
Status ListDelete_L(LinkList &L,int i,ElemType &e){ //将线性表L中第i个数据元素删除。通过e将删除的变量保存起来
LNode *p; //删除算法中i的合理取值范围是1~n。
p = L;
LNode *q;
int j = 0;
while(p->next && j<i-1){ //寻找第i-1个结点,并让p指向第i-1个结点。查找删除第1~n个位置的元素
p = p->next;
++j;
} //跳出循环后此时,p所指向的是第i-1个结点
if(!(p->next) || j>i-1) //删除位置不合理 。!(p->next)的意思是p的后继结点不存在。
return ERROR;
q = p->next; //注意//此时p->next指向的是第i个结点。q是临时保存被删除结点的地址,以备将其释放
p->next = q->next; //注意//也可以写成p->next = p->next->next; 即改变删除结点的前驱结点的指针域。
e = q->data; //保存删除结点的数据域
delete q; //释放删除结点的空间
return OK;
}
void CreateList_Head(LinkList &L,int n){ //头插法建立单链表
L = new LNode;
L->next = NULL; //先建立一个带头结点的单链表
for(i=n;i>0;--i){
p = new LNode; //生成新结点p
scanf(&p->data); //输入元素值
p->next = L->next; 插入到头节点。一开始L->next指向为null,新结点指向null
L->next = p; 头结点指向新结点
}
}
void CreateList_R(LinkList &L,int n){ //尾插法。正位序输入n个元素的值,建立带表头节点的单链表L
L = new LNode;
L->next = NULL;
LNode *r;
r = L; //尾指针r指向头结点
for(i=0;i<n;++i){
p = new LNode; //生成新结点p
scanf(&p->data); //输入元素值
p->next = NULL;
r->next = p; //插入到表尾 ,将新结点放在尾结点的后面
r = p; //r指向新的尾结点 。新插入的结点就是现在新的尾结点了
}
}
int main()
{
}