码迷,mamicode.com
首页 > 编程语言 > 详细

c语言有头循环单链表

时间:2014-10-16 19:02:43      阅读:228      评论:0      收藏:0      [点我收藏+]

标签:c有头循环单链表实现

/*************************************************************************
    > File Name: singleLineTable.c
    > Author: zshh0604
    > Mail: zshh0604@.com 
    > Created Time: 2014年10月15日 星期三 11时34分08秒
 ************************************************************************/

#include<stdio.h>
#include<stdlib.h>
#include<string.h>

/***
 *   循环单链表。 
 *    
 *   学生结构体:
 *		id: 学生编号
 *		name:学生姓名
 *		math:分数
 *		next:指向下一个学生结构体
 */
typedef struct student {
	int id; 
	char name[20];
	int math;
	struct student * next;
}stu;


typedef int cmp_stu(const void * ,const void *);

/****
 *  函数功能:
 *		创建一个头节点。
 *	函数参数:
 *		void.
 *	函数的返回值:
 *		返回头节点指针。
 */
stu * create(void)
{
	stu *head = NULL;
	stu *p = NULL;
	stu *new = NULL;
	int tmpId = 0 ;
	char tmpName[20];
	int tmpMath;	
	
	head =(stu*) malloc(sizeof(stu));
	if(head == NULL)
	{
		printf("分配stu地址空间失败!!!\n");
		return NULL;
	}
	
	head->id = 0;	
	strncpy(head->name,"\0");	
	head->math = 0;	
	
//	head->next = NULL;   //单链表
	head->next = head;	   //有头循环单链表	
	p = head;             //当头创建出来之后应该将指针指向该头部。

	while(1)
	{
		new = (stu*) malloc(sizeof(stu));
		if(new==NULL)
		{
			printf("malloc new error\n");	
			return NULL;
		}
		tmpId++;
		if(tmpId == 3)
		{
			break;
		}

		new->id = tmpId;

		printf("\nname=");
		scanf("%s",tmpName);
		strncpy(new->name,tmpName,20);
		
		printf("math=");
		scanf("%d",&tmpMath);
		new->math = tmpMath;

		p->next = new; 
		p = new;
		//new ->next = NULL;  //单链表
		new->next = head;  //有头循环单链表
	}
	return head;
}

/***
 *  函数功能:
 *		打印输出单链表中的数据。
 *	函数参数:
 *		head 是链表的头。
 *	返回值:
 *		没有返回值
 */
void printf_list(stu *head)
{
	stu *tmp = NULL;
	int i = 0;
	if(head== NULL)
	{
		return;
	}
	tmp = head->next;
#if	1				  //有头循环单链表 
	while(tmp!=head)
	{	
		i++;
		printf("name = %s\n",tmp->name);
		printf("math = %d\n",tmp->math);
		tmp = tmp->next;
	}
#else
	while(tmp!=NULL)  //单链表
	{	
		i++;
		printf("name = %s\n",tmp->name);
		printf("math = %d\n",tmp->math);
		tmp = tmp->next;
	
#endif
	printf("len = %d\n",i);
}
/*****
 *  函数功能:
 *		比较函数。
 *  函数参数:
 *
 *  函数返回值:
 *		返回0表示成功。
 *	    返回1表示失败? 
 * */
int cmp(const void * data, const void * key)
{
	stu * head = NULL;
	int * tmpkey =NULL;
	head = (stu*) data;
	tmpkey=(int*)key;
	//printf("head->id = %d, tmpkey = %d",((stu*)data)->id, *tmpkey);
	if(head->id == *tmpkey)
	{
		return 0;
	}
	return 1;
}

/****
 *
 *	函数功能:
 *		查找一个节点中的数据。
 *	函数参数:
 *		
 *	函数返回值:
 *		返回0查找成功,返回1查找失败。
 */
void * find_stu(stu* head,cmp_stu* cmps, const void *key)
{
	stu * tmp = NULL;
	tmp = head->next;
	
	if(key == NULL)
	{
		return NULL;
	}

#if 1  //循环单链表
	if(cmps((const void *)head, (const void *)key) == 0)
	{
		printf("name = %s\n",tmp->name);
		printf("math = %d\n",tmp->math);
		return tmp;
	}
	while(tmp != head)
	{
		if (cmps((const void *) tmp,(const void * )key)==0)
		{
			printf("name = %s\n",tmp->name);
			printf("math = %d\n",tmp->math);
			return tmp;
		}
		tmp = tmp->next;
	}
#else   //单链表
	while(tmp != NULL)
	{
		if (cmps((const void *) tmp,(const void * )key)==0)
		{
			printf("name = %s\n",tmp->name);
			printf("math = %d\n",tmp->math);
			return tmp;
		}
		tmp = tmp->next;	
#endif
	return NULL;
}

/***
 *  函数功能:
 *		插入节点。
 *	函数参数:
 *	    head:链表中的节点。
 *	    new:需要插入的节点。
 *	函数的返回值:
 *		返回0表示插入成功。
 *		返回1表示插入失败。
 */
int insert_tool(stu* head, stu* new)
{
	if(head==NULL||new == NULL)
	{
		return 1;
	}
#if 1 //循环单链表  
	if(head->next == head)
	{
		head->next = new;
		new->next = head;
	}
#else //单链表
	if(head->next == NULL)
	{
		head->next = new;
		new->next = NULL;
	}
#endif
	new->next = head->next;
	head->next = new;
	return 0;
}

/***
 *	函数功能:
 *	 根据名称进行比较。
 *	函数参数:
 *	 data数据,key为要查数据中查找的值。 	
 *	函数的返回值:
 *   返回0成功。返回1失败。
 */
int cmp_name(const void *data, const void *key)
{

	stu *tmp = NULL;
	char *tmpName = NULL;
	if(data== NULL || key == NULL)
	{
		return 1;
	}	
	tmp =(stu *) data;
	tmpName =(char *) key;
	if(strncmp(tmp->name,tmpName, 20)==0)
	{
		return 0;
	}
	return 1;
}

/***
 *
 *	函数功能:
 *		插入一个节点到链表中。	
 *	函数参数:
 *		head:链表的头节点。
 *		name :要查看的节点的名称。
 *	函数返回值:
 *		返回0插入成功。
 *		返回1插入失败。
 */
int insert_stu(stu* head,char *name)
{	
	stu * tmp = NULL;
	stu * new = NULL;
	char tmpName[20];
	int tmpMath;
	tmp = (stu *)find_stu(head,cmp_name,name);

	if(tmp == NULL)
	{
		printf("没有找到该同学\n");
		return 1;
	}
	new = (stu*) malloc(sizeof(stu));
	
	printf("name=");	
	scanf("%s",tmpName);
	strncpy(new->name,tmpName,20);
	
	printf("math=");
	scanf("%d", &tmpMath);
	new->math  = tmpMath;

	new->id = 10;	
	insert_tool(tmp,new);
	return 0;
}

/**
 *函数功能:
 *	删除制定的节点。
 *参数:
 *  head:链表的头
 *  name:要删除学生的名字。
 *返回值。
 *  0 返回成功。1返回失败。
 */
int delete_stu(stu * head,char *name)
{
	stu * back = NULL;
	stu * p = NULL;
	p = head->next; 
#if 1  //循环单链表 
	if(strcmp(p->name,name)==0)
	{
		head->next = p->next;
		p->next = NULL;
		free(p);
		return 0;
	}
	while(p != head)
	{
		back = p; 
		p = p->next; 
		if(strcmp(p->name,name) == 0)
		{
			back->next = p->next;
			p->next = NULL;
			free(p);
			return 0;
		}
	}

#else  //单链表
	while(p!=NULL)
	{
		back = p; 
		p = p->next; 
		if(strcmp(p->name,name) == 0)
		{
			back->next = p->next;
			p->next = NULL;
			free(p);
			return 0;
		}	
	
#endif
	return 1;
}
/***
 *   函数功能:
 *		销毁链表。
 * 	函数的参数:
 *		链表的头。
 *	函数的返回值
 *		0表示返回成功。1表示返回失败。
 */

int destory_list(stu* head)
{
	stu *tmp;	
	stu *p;
	p = head->next;	
	while(p!=head)
	{	
	    tmp = p; 	
		p = p->next;
		tmp->next = NULL;
		printf("name = %s", tmp->name);
		free(tmp);
	}

}

int main(void)
{
	int i = 2;
	stu * head = NULL;
	head = create();
	printf_list(head);
	find_stu(head,cmp,&i);
	insert_stu(head,"bb");
	printf_list(head);
	printf("----------------------\n");
	destory_list(head);
	head = NULL;
	printf_list(head);
	printf("---------------------\n");
}

c语言有头循环单链表

标签:c有头循环单链表实现

原文地址:http://blog.csdn.net/shaohuazuo/article/details/40151405

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!