c语言单链表订票,c语言实现单链表

一:使用简介

使用c语言实现了单链表的基本操作,代码共有四个文件,两个头文件是常用的,后两个分别是主函数,和对链表的基本操作函数,倒入时候,须将四个文件放在同一个目录下。

二:心得

在书写过程中,主要错误集中在指针的使用上,通过此次编程,对于指针的认识更加深刻,头结点的存在,更大意义上是为了简化指针的操作。

比如在初始化创建头结点的时候,需要改变头指针的指向,众所周知,在函数中改变头指针,必须要传入头指针的地址。如果没有头结点,后期的创建,插入,删除等操作可能都需要改变头指针,显然,每次都传入头指针地址(相当于指针的指针),不便于代码的易读性。如果有了头结点,这个繁琐的问题很轻易地解决了。后期的操作只需要改变头结点的指针域,除了在初始化的时候,需要改变头指针的地址(使其指向头结点),其他操作无需改变,当然在这些操作之前,必须要对链表进行初始化(创建头结点)。

#include

#include

#include

#include

#include

//常用的表示函数结果状态代码

#define OK1

#define ERROR0

typedef int Status ; //返回true or false

//定义链表的结构体

typedef struct Lnode{

Elemtype data;

struct Lnode* next;

}LNODE,*Plist;

//对链表进行的一系列操作

//初始化链表

Status InitList(Plist *p){

//创建头结点,使头指针指向头结点(头指针的指向要改变,所以要修改头指针)

*p=(Plist)malloc(sizeof(LNODE));

if(!(*p)){

//内存分配失败,程序退出

exit(OVERFLOW);

}

//将头结点的指针域置为空,*p为结构体指针,对结构体成员的引用使用->,如果是结构体,直接使用.引用成员

(*p)->next=NULL;

return OK;

}

//销毁单链表,销毁头结点,以及其后面所有有效节点,同时头指针要指向空,防止后面的程序不小心使用

//该过程改变了头指针的指向,所以需要传入头指针的地址,注意,在该过程中,只是修改了头指针的指向,

Status DestroyList(Plist* p){

//每次使用头指针时候,要赋值,保留原来的位置

Plist L=*p;

Plist q;

//如果指针不为空,就一直释放节点

while(L){

q=L->next;

free(L);

L=q;

}

//使头指针指向空

*p=NULL;

return OK;

}

//清除单链表,只是释放有效节点,不释放头结点

Status clearList(Plist p){

//P指向头结点,L指向第一个有效节点

Plist L=p->next,q;

//循环释放节点,知道最后的节点

while(L){

q=L->next;

free(L);

L=q;

}

//头结点的指针域指向空

p->next=NULL;

return OK;

}

//判断链表是否为空

Status EmptyList(Plist p){

int i=0;

Plist L=p->next;

while(L){

i++;

L=L->next;

}

if(i>0){

return OK;

}

return ERROR;

}

//判断链表里面的数据个数

int ListLength(Plist p){

int i=0;

//指向第一个有效节点的指针

Plist L=p->next;

while(L){

i++;

L=L->next;

}

return i;

}

//使用头插法创建单链表,该方法使用前,必须要初始化节点,该方法得到的数据是逆序的,n为要插入的数据个数

//头插法每次在头结点后面插入数据,不改变头指针的指向,所以不要传入头指针的地址

Status CreateList(Plist p,Elemtype e){

//L指向头结点

Plist L=p;

//每次插入的新数据都是第一个有效数据,每次需要修改的只是头指针

Plist node=(Plist)malloc(sizeof(LNODE));

if(!node) exit(OVERFLOW);

node->data=e;

node->next=L->next;

L->next=node;

//printf("插入数据%d\n",e);

return OK;

}

//获取某位置的数据

Status GetElem(Plist p,int i,Elemtype* e){

Plist L=p->next;

int j=1;

//判断该位置是否合理

if(i<1 i="">ListLength(p)){

return ERROR;

}

//找到该位置

while(L&&jnext;

j++;

}

*e=L->data;

return OK;

}

//获取某数据所在位置

int LocateElem(Plist p,Elemtype e){

//L指向第一个有效数据

Plist L=p->next;

int i=1;

while(L){

if(L->data==e){

break;

}

L=L->next;

i++;

}

if(i>ListLength(p)){

//数据不存在

return ERROR;

}

return i;

}

//对链表进行插入

Status InsertList(Plist p,int i,Elemtype e){

int j=0;

//L指向头结点

Plist L=p;

//判断插入位置是否合理

if(i<1 i="">ListLength(L)+1){

return ERROR;

}else{

//寻找插入点的前一个位置

for(;jnext;

}

//分配新节点

Plist node=(Plist)malloc(sizeof(LNODE));

if(!node) exit(OVERFLOW);

node->data=e;

//执行插入

node->next=L->next;

L->next=node;

return OK;

}

}

//对链表数据进行删除,并返回删除的数据

Status DeletList(Plist p,int i,Elemtype* e){

int j=0;

//L指向头结点

Plist L=p;

//判断链表是否为空

if(!ListLength(p)){

return ERROR;

}else if(i<1 i="">ListLength(L)){

//判断删除位置是否合理

return ERROR;

}else{

//寻找删除点的前一个位置

for(;jnext;

}

//保存将要删除的节点

Plist node=L->next;

*e=node->data;

L->next=node->next;

//释放节点

free(node);

return OK;

}

}

//显示链表的操作,传入链表的头指针

void showList(Plist p){

//指向第一个有效节点的指针

Plist q=p->next;

while(q){

printf("%d\n",q->data);

q=q->next;

}

}

1>1>1>

#include "c-1.h"

//定义抽象数据的数据类型

typedef int Elemtype;

#include "c-2.h"

#include "operate.cpp"

int main(){

//创建一个结构体指针,使其指向空,该指针是链表的头指针

Plist p=NULL;

int len=0,i=0;

Elemtype e,val;

//*******************初始化链表

if(InitList(&p)){

printf("初始化成功\n");

}

//******************头插法创建链表

printf("请输入链表长度\n");

scanf("%d",&len);

for(i=0;i

printf("请输入第%d个数据:\n",i+1);

scanf("%d",&e);

CreateList(p,e);

}

printf("链表长度是%d\n",ListLength(p));

printf("遍历链表:\n");

//显示链表

showList(p);

//******************尾插法创建链表

/*printf("请输入链表长度\n");

scanf("%d",&len);

Plist q=p;

while(idata=e;

node->next=NULL;

q->next=node;

//保存最后一个节点的指针,用于下次在结尾添加数据

q=node;

i++;

}

printf("链表长度是%d\n",ListLength(p));

printf("遍历链表:\n");

//显示链表

showList(p);*/

//********************销毁单链表

/*DestroyList(&p);

if(p==NULL){

printf("销毁成功");

}else{

printf("销毁失败");

}*/

//*************清空链表,有效节点都被释放

/*clearList(p);

printf("链表长度是%d\n",ListLength(p));*/

//**********************执行插入操作

/*if(InsertList(p,3,7)){

printf("插入成功\n");

}else{

printf("插入失败\n");

}*/

//**********************执行删除操作

/*if(DeletList(p,3,&val)){

printf("删除成功,删除数据是%d\n",val);

}else{

printf("删除失败\n");

}*/

//**********************获取某位置的数据

if(GetElem(p,4,&val)){

printf("查找成功,查找数据是%d\n",val);

}else{

printf("查找失败\n");

}

//**********************获取某数据所在的位置

if(LocateElem(p,3)){

printf("查找成功,所在位置是%d\n",LocateElem(p,3));

}else{

printf("数据不存在,查找失败\n");

}

//showList(p);

return 0;

}

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值