c语言有头循环单链表

/*************************************************************************
    > File Name: singleLineTable.c
    > Author: zshh0604
    > Mail: [email protected]
    > 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");
}

时间: 2024-09-27 21:58:08

c语言有头循环单链表的相关文章

【C语言数据结构】循环单链表

CircleLinkList.h #ifndef CIRCLE_LINK_LIST #define CIRCLE_LINK_LIST //链表节点 typedef struct _CircleLinkListNode {     struct _CircleLinkListNode *next; }CircleLinkListNode; //循环单链表 typedef void CircleLinkList; /*  * 创建循环单链表  * @return 返回循环单链表的指针  */ Cir

c语言循环单链表

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

链表之循环单链表(用C语言描述)

上回说到建立链表的三种形式,分别是头插法,尾插法,和尾插法MAX?? ??下面讲一下循环单链表?? 循环单链表,字面意思,就是单链表循环了起来,尾节点在输入结束后不会指向NULL,而是指向了头节点head 酱紫,链表就循环了起来 下面是代码实现 #include <stdio.h> #include <stdlib.h> typedef char datatype; typedef struct node { datatype data; struct node *next; in

数据结构之---c语言实现循环单链表操作

//=========杨鑫========================// //循环单链表的实现 #include <stdio.h> #include <stdlib.h> typedef int ElemType; //定义结点类型 typedef struct Node { ElemType data; struct Node *next; }Node,*LinkedList; int count = 0; //1.单循环链表的初始化 LinkedList init_ci

02循环单链表

循环单链表定义:将单链表中终端结点的指针端由空指针改为指向头结点,就使整个单链表形成了 一个环,这种头尾相接的单链表成为单循环链表. 循环链表的数据结构: 1 /* c2-2.h 线性表的单链表存储结构 */ 2 struct LNode 3 { 4 ElemType data; 5 struct LNode *next; 6 }; 7 typedef struct LNode *LinkList; /* 另一种定义LinkList的方法 */ 代码实现: 1 2 3 /* bo2-4.c 设立

循环单链表

//函数声明部分:#include"CirLinkList.h" #define _CRT_SECURE_NO_WARNINGS 1 #include<stdio.h> #include<stdlib.h> typedef int ElemType; typedef struct linknode { ElemType data; struct linknode *next; }node; void judgement_NULL(node * p); node 

_DataStructure_C_Impl:循环单链表

//CycList:循环单链表 #include<stdio.h> #include<stdlib.h> typedef int DataType; typedef struct Node{ DataType data; struct Node *next; }ListNode,*LinkList; //创建一个不带头结点的循环单链表 LinkList CreateCycList(int n){ DataType e; LinkList head=NULL; ListNode *p

【线性表5】线性表的链式实现:循环单链表

简介 循环单链表 是在在单链表的基础上,用最后的一个结点的指针域指向头结点形成的.因此它在逻辑上是一个环形结构. 循环单链表在实际编程中很少用. 要点:1.遍历结束的标志是 p == [头结点地址],而不是p==NULL 2.表为空的判断标志是:   if( head->next == head   ) 3.在单循环链表中,从任一结点出发都可访问到表中所有结点 循环链表一般还使用尾指针rear保存最后一个结点的地址,因为使用尾指针既可以快速找到 最后一个结点,也可以快速找到头结点. 简单的代码实

【c++版数据结构】之循环单链表的实现(带头结点以及尾节点)

所实现的循环单链表的结构如下图所示: 循环单链表的实现,和上一篇文章单链表的实现大致相同点击打开链接,略有区别: 1:循环判断的条件不再是s == NULL或者s->next == NULL,而是他们是否等于头指针.2: 断开链表时的处理,尾节点的next不是NULL,而是指向头结点 具体细节参考上一篇文章 头文件:SCList.h #ifndef SCLIST_H #define SCLIST_H #include<iostream> #include<cassert> u