# include <stdio.h>
# include <stdlib.h>
# include <malloc.h>
# define StopCondition t!=0 /***根据实际程序需要修改***/
typedef int DataType; /***根据实际程序需要修改***/
typedef struct node{
DataType data;
struct node *next;
}Node;
typedef Node* LinkList;
/*****根据实际程序需要修改*******/
static void GetData(DataType *pdata);
static void TraverseFunc(DataType tdata);
/***********END*************/
/***********ADT接口声明***************/
void InitList(LinkList *pphead);
void CreatList(LinkList *pphead);
int DeleteNode(LinkList *pphead,int n,DataType *pdata);
int InsertNode(LinkList *pphead,int n,DataType tdata);
void TraverseList(LinkList*pphead,void(*pfunc)(DataType));
unsigned int ListLength(LinkList *pphead);
int ListIsEmpty(LinkList *pphead);
void DestroyList(LinkList *pphead);
/**************END***********/
int main (void)
{
LinkList mylist;
DataType t= 100;
DataType data;
int n;
InitList(&mylist);
puts("请输入数据,输入 0 结束输入");
CreatList(&mylist);
puts("数据录入成功");
TraverseList(&mylist,&TraverseFunc);
#if 0
puts("开始删除测试");
while(!ListIsEmpty(&mylist))
{
scanf("%d",&n);
DeleteNode(&mylist,n,&data);
printf("%d已成功删除\n",data);
}
# endif
DestroyList(&mylist);
return 0;
}
static void GetData(DataType *pdata) ///
{
int ch;
while(1!=scanf("%d",pdata))
{
fputs("illegal input,try again !\n",stderr);
while((ch=getchar())!=EOF && ch!='\n')
continue ;
}
return ;
}
static void TraverseFunc(DataType tdata)
{
printf("%d\n",tdata);
return ;
}
void InitList(LinkList *pphead)
{
*pphead=(Node*)malloc(sizeof(Node));
if(*pphead==NULL)
{
fputs("memory allocate error!\n",stderr);
exit(EXIT_FAILURE);
}
(*pphead)->next=NULL;
return ;
}
void CreatList(LinkList *pphead)
{
Node * p1, *p2;
DataType t;
GetData(&t);
while(StopCondition)
{
p1=(Node*)malloc(sizeof(Node));
if(p1==NULL)
{
fputs("memory allocate error!\n",stderr);
exit(EXIT_FAILURE);
}
p1->data=t;
p1->next=NULL;
if((*pphead)->next==NULL)
(*pphead)->next=p1;
else
p2->next=p1;
p2=p1;
GetData(&t);
}
return ;
}
int DeleteNode(LinkList *pphead,int n,DataType *pdata)
{
int j = 1 ;
Node*pt;
Node*p=*pphead;
if(n<1)
return 0;
while(p->next!=NULL && j< n)
{
p=p->next;
++j;
}
if(p->next==NULL)
return 0;
pt=p->next; //pt保存待删除节点地址
*pdata=pt->data; //取出节点的数据
p->next=p->next->next; //跨越待删节点 再连接
free(pt);
return 1;
}
int InsertNode(LinkList *pphead,int n,DataType tdata)
{ //将tdata数据所在的结点插为第n个结点
int j =1;
Node*p=*pphead;
Node*pnew;
if(n<1)
return 0;
while(p!=NULL && j< n)
{
p=p->next;
++j;
}
if(p==NULL) //插入的位置不在范围内
return 0;
pnew=(Node*)malloc(sizeof(Node));
if(pnew==NULL)
return 0;
pnew->data=tdata; //存入结点数据
pnew->next=p->next; //新节点连接后面的结点
p->next=pnew; //新节点被前面连接
return 1;
}
void TraverseList(LinkList*pphead,void(*pfunc)(DataType))
{
Node*p=(*pphead)->next; //取出第一个数据结点的指针
while(p!=NULL)
{
(*pfunc)(p->data); //函数作用与节点数据
p=p->next;
}
return ;
}
unsigned int ListLength(LinkList *pphead)
{
Node*p=(*pphead)->next; //取出第一个数据结点的指针
unsigned count = 0;
while(p!=NULL)
{
p=p->next;
++count;
}
return count;
}
int ListIsEmpty(LinkList *pphead)
{
return (*pphead)->next==NULL;
}
void DestroyList(LinkList *pphead)
{
Node*p=*pphead;
Node*pt;
while(p!=NULL)
{
pt=p; //临时保存待释放的目标结点
p=p->next; //后移
free(pt);
}
return ;
}
1.为了统一接口,函数都是用了2级指针:LinkList *,调用时都使用LinkList*类型
2.用Node**对ADT接口实现来说更加直观,但是鉴于一般编译器都有函数接口类型提示效果,所以接口都做了修改。用LinkList* 而不是Node**
3.优化,使更加适合重用。上面的main函数用来驱动测试,实际开发一般多文件分开写。