您的位置:首页 > 编程语言 > C语言/C++

关于链表的创建和对链表的操作--C语言

2015-05-29 08:37 555 查看

一、关于链表的创建和对链表的操作

1、关于链表的类型

(1)链表结点的数据项类型

typedef char EleType;

(2)链表结点的类型

typedef struct node{

EleType data;

struct node *next;

}ChainNode;

(3)链表指针类型

typedef struct {

ChainNode*head;

ChainNode *tail;

}List;

1、创建线性表结点的函数(tail尾指针不参与工作)

/*创建一个存储元素的节点。入口参数为存储在新创建结点中的数据元素的值。返回节点指针,非0表示成功,0表示不成功。*/

piont*creatpiont(eletype data){

piont *p;

p=(piont *)malloc(sizeof(piont));

if(!p)return 0;

p->data=data;

p->next=0;

return p;

}

如下图:



3、创建线性表函数(需要使用tail尾指针)

/*创建线性表,返回线性表的指针*/

list*creatlist(void){

list *p;

eletype *data=0;

p=(list *)malloc(sizeof(list));

p->head=creatpiont(*data);

if(!(p->head)){free(p);return 0;}

p->tail=p->head;

return p;

}

下图:



4、在线性表最后一个元素追加元素的函数(需要修改tail尾指针)

/*追加元素,在线性表最后一个元素的后面加一个元素。入口参数为线性表的指针,和要追加的数据。返回操作是否成功,1表示成功,0表示不成功*/

intlistappend(list *pl,eletype data){

piont *newp;

newp=creatpiont(data);

if(!newp)return 0;

if(!(pl->head))return 0;

pl->tail->next=newp;

pl->tail=newp;

return 1;

}

下图:



5、取到线性表元素(结点)的地址的函数(不需要修改tail尾指针)

/*取编号为n的元素所在的结点的地址。入口参数为线性表的指针、编号。返回结点指针,非0表示成功,0表示失败。*/

piont*getaddr(list *pl,int n){

piont *p;

int a;

if(!(pl->head))return 0;

if(n<0)return 0;

a=0;

p=pl->head;

while(p&&a<n){

p=p->next;

a++;

}

return p;

}

如下图:



6、删除线性表元素的函数(需要修改tail尾指针)

/* 删除元素,删除编号为n的元素,入口参数为线性表的指针、编号。操作成功返回1 ,失败返回0 */

intdeletepiont(list *pl,int n){

piont *fp;

piont *p;

if(!pl->head->next)return0;

p=getaddr(pl,n-1);

if(!(p&&p->next))return0;

fp=p->next;

p->next=p->next->next;

if(!(p->next->next))

pl->tail=p;

free(fp);

return 1;

}

如下图(1):



7、清空线性表函数(不需要修改tail尾指针)

/*清空线性表,即删除所有元素。入口参数为线性表的指针*/

int clearlist(list*pl){

while(deletepiont(pl,1));

return 1;

}

8、撤销线性表函数(不需要修改tail尾指针)

/*撤销线性表,入口参数为线性表的指针*/

int freelist(list*pl){

clearlist(pl);

free(pl->head);

free(pl->tail);

free(pl);

pl->head=0;

return 1;

}

9、往线性表插入元素的函数(需要修改tail尾指针)

/*加入元素,在线性表编号为N的元素的前面加一个元素。入口参数为线性表的指针、编号和要加入的数据。返回操作是否成功,1表示成功,0表示不成功*/

intlistinsert(list *pl,int n,eletype data){

piont *p;

piont *newp;

p=getaddr(pl,n-1);

if(!p)return 0;

newp=creatpiont(data);

if(!newp)return 0;

newp->next=p->next;

p->next=newp;

if(!p->next)

pl->tail=newp;

return 1;

}

如下图(1):



10、取线性表的元素的函数(不需要修改tail尾指针)

/*取元素,取编号为N的元素的值。入口参数为线性表的指针、编号和要存储读取的值的EleType型内存单元(变量)的地址。返回操作是否成功,1表示成功,0表示不成功*/

int getdata(list*pl,int n,eletype *data){

piont *p;

p=getaddr(pl,n);

if(!p)return 0;

*data=p->data;

return 1;

}

如下图:



11、遍历线性表的每一个元素的函数(不需要修改tail尾指针)

/*遍历,一次访问线性表中的每一个元素,每访问一个元素都用某个函数对这个元素进行某种处理。遍历了全部元素返回0,否则返回当前访问元素的编号。*/

intlistbianli(list *pl,int (*f)(eletype *data)){

piont *p;

int a=0;

for(p=pl->head->next;p;p=p->next){

if(!f(&(p->data))) returna+1;

a++;

}

return 1;

}

二、把以上的代码封装在文件 list.h中 ,就是写在list.h里

List.h文件内容如下:

typedef char eletype;

typedef structnode{

eletype data;

struct node *next;

}piont;

typedefstruct {

piont *head;

piont *tail;

}list;

/* 注意:如果你写的链表函数没有顺序,那么请先申明

piont*creatpiont(eletype data);

list*creatlist(void);

intlistappend(list *pl,eletype data);

piont*getaddr(list *pl,int n);

intdeletepiont(list *pl,int n);

intclearlist(list *pl);

intfreelist(list *pl);

intlistinsert(list *pl,int n,eletype data);

intlistbianli(list *pl,int (*f)(eletype *data));

intgetdata(list *pl,int n,eletype *data);

*/

piont*creatpiont(eletype data){

piont *p;

p=(piont *)malloc(sizeof(piont));

if(!p)return 0;

p->data=data;

p->next=0;

return p;

}

list*creatlist(void){

list *p;

eletype *data=0;

p=(list *)malloc(sizeof(list));

p->head=creatpiont(*data);

if(!(p->head)){free(p);return 0;}

p->tail=p->head;

return p;

}

intlistappend(list *pl,eletype data){

piont *newp;

newp=creatpiont(data);

if(!newp)return 0;

if(!(pl->head))return 0;

pl->tail->next=newp;

pl->tail=newp;

return 1;

}

piont*getaddr(list *pl,int n){

piont *p;

int a;

if(!(pl->head))return 0;

if(n<0)return 0;

a=0;

p=pl->head;

while(p&&a<n){

p=p->next;

a++;

}

return p;

}

intdeletepiont(list *pl,int n){

piont *fp;

piont *p;

if(!pl->head->next)return0;

p=getaddr(pl,n-1);

if(!(p&&p->next))return0;

fp=p->next;

p->next=p->next->next;

if(!(p->next->next))

{

pl->tail=p;

}

free(fp);

return 1;

}

int clearlist(list*pl){

while(deletepiont(pl,1));

return 1;

}

int freelist(list*pl){

clearlist(pl);

free(pl->head);

free(pl->tail);

free(pl);

return 1;

}

intlistinsert(list *pl,int n,eletype data){

piont *p;

piont *newp;

p=getaddr(pl,n-1);

if(!p)return 0;

newp=creatpiont(data);

if(!newp)return 0;

newp->next=p->next;

p->next=newp;

if(!p->next){pl->tail=newp;}

return 1;

}

intlistbianli(list *pl,int (*f)(eletype *data)){

piont *p;

int a=0;

for(p=pl->head->next;p;p=p->next){

if(!f(&(p->data))) returna+1;

a++;

}

return 1;

}

int getdata(list*pl,int n,eletype *data){

piont *p;

p=getaddr(pl,n);

if(!p)return 0;

*data=p->data;

return 1;

}

三、编写程序检验以上线性表的各函数功能是否正确

#include"list.h" /*注意包含*/

int prin(eletype*data){

printf("%c",*data);

}

void show(list*pl){

listbianli(pl,prin);

printf("\n");

}

eletype *a="havea dream?";

main(){

int b[10]={0,1,15,2,3,3,2,3,1,23};

char *c="Zo!o u yDX";

inte[14]={0,21,13,17,3,16,11,14,1,10,11,1,9,10};

list *pl;

int n;

int g[]={1,8,6,5,10};

eletype h;

pl=creatlist();

for(n=0;a
;n++) listappend(pl,a
);

show(pl);

for(n=0;c
;n++){

listinsert(pl,b
,c
);

}

show(pl);

for(n=0;n<14;n++){

deletepiont(pl,e
);

}

show(pl);

for(n=0;n<4;n++){

getdata(pl,g
,&h);

printf("%c",h); }

clearlist(pl);

show(pl);

freelist(pl);

}

编译连接显示,结果是:

内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: