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 = tmpId;
	
	printf("name =");
	scanf("%s",tmpName);
	strncpy(head->name,tmpName,20);
	
	printf("math =");
	scanf("%d",&tmpMath);
	head->math = tmpMath;	
	
//	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				  //循環單鏈表 
	printf("name = %s\n",head->name);
	printf("math = %d\n",head->math);
	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; 
#if 1  //循環單鏈表 
	while(p!=head)
	{
		back = p; 
		p = p->next; 
		if(strcmp(p->name,name) == 0)
		{
			back->next = p->next;
			p->next = head;
			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");
}

發佈了58 篇原創文章 · 獲贊 65 · 訪問量 12萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章