链表接口的实现


# 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函数用来驱动测试,实际开发一般多文件分开写。

 





评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值