//库函数头文件的包含
#include <stdio.h>
#include <stdlib.h>
#include <malloc.h>
//函数状态码定义
#define TRUE 1
#define FALSE 0
#define OK 1
#define ERROR 0
#define OVERFLOW -2
typedef int Status;
typedef int ElemType; //假设线性表中的元素均为整型
//---------线性表的单链表存储结构--------------
typedef struct LNode
{
ElemType data;
struct LNode *next;
}LNode,*LinkList;
//初始化一个空的链表
Status InitList_L(LinkList &L){
L = (LinkList)malloc(sizeof(LNode)); //开辟一个头结点
if(!L) //存储空间开辟失败
exit(OVERFLOW);
L->next = NULL; //头结点的next赋值为空
return OK;
}
//向链表末尾插入数据元素
Status InsertList_L(LinkList &L, ElemType e){
LNode *p = L, *insertPtr;
while(p->next){
p = p->next;
}
insertPtr = (LNode *)malloc(sizeof(LNode));
if(!insertPtr)
exit(OVERFLOW);
insertPtr->data = e;
insertPtr->next = NULL;
p->next = insertPtr;
return OK;
}
//返回链表的长度
int ListLength_L(LinkList L){
LNode *p = L;
int len = 0;
while(p->next){
p = p->next;
++len;
}
return len;
}
//在带头结点的单链线性表L中第i个位置之前插入元素e
Status ListInsert_L(LinkList &L, int i, ElemType e){
LNode *p = L, *insertPtr;
i--;
while(i-- && p->next){
p = p->next;
}
if(!p->next)
return ERROR;
insertPtr = (LNode *)malloc(sizeof(LNode));
insertPtr->data = e;
insertPtr->next = p->next;
p->next = insertPtr;
return OK;
}
//返回第i个元素的值
Status GetElem_L(LinkList L, int i, ElemType &e){
LNode *p = L;
while(i-- && p->next){
p = p->next;
}
if(i > 0)
return ERROR;
e = p->data;
return OK;
}
//删除链表中第i个元素并返回其值
Status ListDelete_L(LinkList &L, int i, ElemType &e){
LNode *p = L, *delPtr;
i--;
while(i-- && p->next){
p = p->next;
}
delPtr = p->next;
e = delPtr->data;
if(delPtr->next)
p->next = delPtr->next;
else
p->next = NULL;
free(delPtr);
return OK;
}
//若cur_e是L的数据元素,且不是第一个,则用pre_e返回它的前驱,否则操作失败pre_e无定义
Status PriorElem_L(LinkList L, ElemType cur_e, ElemType &pre_e){
LNode *p = L->next;
if(p->data == cur_e)
return ERROR;
while(p){
if(p->next->data == cur_e)
break;
p = p->next;
}
pre_e = p->data;
return ERROR;
}
//若cur_e是L的数据元素,且不是最后一个,则用next_e返回它的后继,否则操作失败next_e无定义
Status NextElem_L(LinkList L, ElemType cur_e, ElemType &next_e){
LNode *p = L;
while(p->next){
if(p->next->data == cur_e)
break;
p = p->next;
}
p = p->next;
if(p->next)
next_e = p->next->data;
else
return ERROR;
return OK;
}
//visit()函数
Status Print(LNode p){
printf("%d ", p.data);
return OK;
}
//单链线性链表的遍历
Status TraverseList_L(LinkList L, Status (*visit)(LNode)){
LNode *p = L;
while(p->next){
if(!visit(*(p->next)))
return ERROR;
p = p->next;
}
return OK;
}
//销毁链表
Status DestroyList_L(LinkList &L){
LNode *p;
while(L){
p = L->next;
free(L);
L = p;
}
return OK;
}
//清空链表
Status ClearList_L(LinkList &L){
LNode *p, *q;
p = L->next;
while(p){
q = p->next;
free(p);
p = q;
}
L->next = NULL;
return OK;
}
//判断链表是否为空
bool Is_EmptyList(LinkList &L){
if(L->next == NULL)
return true;
return false;
}
//单链表的就地逆置
void ListReverse_L(LinkList &L){
//单链表为空或只有头结点或只有一个元素,不用进行逆置操作
if(L != NULL && L->next != NULL && L->next->next != NULL){
LNode* p = L->next->next; //令p指向线性表中第2个元素a2
L->next->next = NULL; //令线性表中第1个元素a1的next为空
LNode *tp; //临时变量
while(p){
tp = p->next; //保存p->next的地址
p->next = L->next;
L->next = p; //将p插入到头结点之后
p = tp; //继续访问下一个元素
}
}
}
//主函数
int main(){
LinkList L;
int a;
InitList_L(L); //初始化以带头结点的单链表
printf("请输入5个数字用来创建链表:\n");
for(int i = 0; i < 5; i++){
scanf("%d", &a);
InsertList_L(L, a);
}
printf("下面是遍历操作的的结果:\n");
TraverseList_L(L, Print);
printf("\n下面是删除第5个元素操作后的结果:\n");
ListDelete_L(L, 5, a);
TraverseList_L(L, Print);
printf("\n下面是就地逆置操作的结果:\n");
ListReverse_L(L);
TraverseList_L(L, Print);
printf("\n下面是求链表长度操作的结果:\n");
printf("%d", ListLength_L(L));
printf("\n下面是输出返回2的前驱的结果:\n");
PriorElem_L(L, 2, a);
printf("%d", a);
DestroyList_L(L);
return 0;
}
线性表的链式表示和实现
最新推荐文章于 2021-11-27 23:02:23 发布