关于链表的创建和对链表的操作--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);
}
编译连接显示,结果是:
相关文章推荐
- vc++使用GDI+的准备工作
- 传智播客c/c++公开课学习笔记--C语言与木马恶意代码分析和360安全防护揭秘
- C++基础学习—定义类和对象
- C++基础学习—面向对象基础
- C++基础学习—函数
- C++基础学习—vector
- 【末世旅行之C++】C++中一个冒号和两个冒号的用法
- C语言优先级之计算总结
- 基于C语言sprintf函数的深入理解
- 黑马程序员-C语言数组与指针学习心得
- C++:STL标准入门汇总
- YTU 2419: C语言习题 等长字符串排序
- C++实现一个航空订票程序 来自明桑Android
- 八皇后 c语言递归实现方法(带注释)
- C++简单贪吃蛇实现
- 3d数学基础-4x4齐次矩阵-用C++代码实现
- Broken Keyboard
- 对C++中迭代器的认识
- poj2039---写出c++reverse函数,且且依次输出每一行的第一个、第二个.....
- c语言中int long float double 等类型所占字节及输出表示