一个复杂一点的单向链表

/**********************************************************************************
*										  *					
* 作者:杨志永                                                                    *
*  日期:2012-05-13                                                                *
*  QQ:929168233                                                                   *
*  Email:ljy520zhiyong@163.com                                                    *
*                                                                                 *
*  文件名: linkList.c                                                             *
*                                                                                 *
*  功能:创建链表,添加节点,求链表的长度                                            *  
*                                                                                 *
***********************************************************************************/

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

#define TRUE 1
#define FALSE 0

#define DEBUG FALSE		//标识是否处理调试介段

#define N 80			//最大的名字的字符个数

static int count = 0; 		//标识链表中的成员是第count次插入的

struct Student
{
	char name[N+1];		//学生的名字
	int age;		//学生的年龄
};

struct list
{
	struct Student * student;	//链表节点中有一个学生成员
	int length;			//标识该成员是第length次插入的

	struct list * next;		//指向下一个链表的成员
};

struct list * initList(void);		//初始化链表并返回头指针
_Bool add_member(struct list * linkList, int position, struct Student node); 	//在链表linkList中的第position位置中插入一个学生成员node,并返回结果.1为成功插入;0为插入失败
void showLinkList(struct list * linkList, int length);				//打印链表中的所有成员
int linkListLength(struct list * linkList);					//求出链表的长度,并返回该长度

int main(void)
{
	struct list * linkList = NULL;						//用于接收初始化链表的头指针

	struct Student student1 = {"yangzhiyong1", 11};				//结构体学生变量并初始化
	struct Student student2 = {"yangzhiyong2", 12};
	struct Student student3 = {"yangzhiyong3", 13};
	struct Student student4 = {"yangzhiyong4", 14};
	
	linkList = initList();							//初始化链表并接收其链表的头指针
	
	if ( add_member(linkList, 1, student1) )				//添加一个学生成员,并放在原有链表中的第一个位置
	{
		if(DEBUG)
		{
			printf("添加成功!\n");
		}
	}
	else
	{
		if (DEBUG)
		{
			printf("添加失败!\n");
		}
	}
	
	if ( add_member(linkList, 1, student2) )				//添加一个学生成员,并放在原有链表中的第一个位置
	{
		if(DEBUG)
		{
			printf("添加成功!\n");
		}
	}
	else
	{
		if (DEBUG)
		{
			printf("添加失败!\n");
		}
	}
	
	if ( add_member(linkList, 1, student3) )				//添加一个学生成员,并放在原有链表的第一个位置
	{
		if(DEBUG)
		{
			printf("添加成功!\n");
		}
	}
	else
	{
		if (DEBUG)
		{
			printf("添加失败!\n");
		}
	}

	if ( add_member(linkList, 1, student4) )				//添加一个学生成员,并放在原有链表的第一个位置
	{
		if(DEBUG)
		{
			printf("添加成功!\n");
		}
	}
	else
	{
		if (DEBUG)
		{
			printf("添加失败!\n");
		}
	}
	//以上四个插入操作,使得链表中成员的顺序为:student4->student3->student2->student1,即反序插入

	int length = linkListLength(linkList);					//获取链表的长度(不包括其头指针)
	printf("linkList's lenght is %d\n", length);
	showLinkList(linkList, length);						//打印链表,第一个参数为链表的头指针,第二个为链表的长度
	free(linkList);								//程序结束后释放其链表的内存空间
	linkList = NULL;							//并使链表的头指针置空
	if (DEBUG)
	{
		printf("释放linkList内存成功!\n");
	}
	exit(EXIT_SUCCESS);							//成功退出程序
}

struct list * initList(void)
{
	if (DEBUG)
	{
		printf("开始初始化链表空间\n");
	}
	struct list * linkList = (struct list *)malloc( sizeof(struct list) );
	struct Student * student = (struct Student *)malloc( sizeof(struct Student) );

	if ( linkList==NULL || student==NULL)
	{
		printf("在文件%s第%d行中分配内存失败!\n", __FILE__, __LINE__);
		exit(EXIT_FAILURE);
	}
	else
	{
		if (DEBUG)
		{
			printf("初始化分配内存空间成功!\n");
		}
	}
	
	linkList->student = student;
	strcpy(linkList->student->name, "默认值");
	linkList->student->age = 0;

	linkList->length = count++;
	linkList->next = NULL;

	if (DEBUG)
	{
		printf("初始化完毕\n");	
	}

	return linkList;	
}

_Bool add_member(struct list * linkList, int position, struct Student node)
{
	_Bool flag = 0;				//判断是否成功插入到链表
	int i = 0;				
	struct list * head = linkList;		//声明一个链表的指针,并将头指针赋值给它,用于操作链表而又不影响原有链表的头指针

	struct list * new_node = (struct list *) malloc( sizeof(struct list) );	//分配一个新节点的内存空间
	struct Student * new_student = (struct Student *) malloc( sizeof(struct Student) );	//分配个学生结构体的内存空间

	int length = linkListLength(head);							//获取链表的长度
	
	if ( new_node==NULL || new_student==NULL || linkList==NULL )				//如果分配内存空间出错则退出
	{
		printf("在文件%s第%d行中分配新节点内存失败!\n", __FILE__, __LINE__);
		exit(EXIT_FAILURE);
	}
	else
	{
		if (DEBUG)
		{
			printf("添加元素中分配内存成功呀!\n");
		}
	}

	if ( position < 1 || position > length + 1 ) 						//判断插入的位置是否合法不能插在头结点的前面
	{											//也不能插入在原有链表长度+1之后的位置
		if (DEBUG)
		{
			printf("插入的位置出错啦\n");
		}
		return flag;
	}
	else
	{
		if (DEBUG)
		{	
			printf("插入的位置合法!\n");
		}
	}
	
	if ( length < 1 )									//判断是否是第一次插入节点
	{
		while( linkList->next )								
		{
			linkList = linkList->next;
		}
		
		if (DEBUG)
		{
			printf("开始初始化新添加的元素的值\n");
		}
	
		new_node->student = new_student;						//初始化链表节点的student成员
		strcpy( new_node->student->name ,node.name );					//初始化链表节点中的student成员中的name成员
		new_node->student->age = node.age;						//初始化锭表节点中的student成员中的age成员

		new_node->length = count++;							//标识是第count次插入的数据

		linkList->next = new_node;							//将头指针指向该节点的首地址
		new_node->next = NULL;								//并将该节点的下一个成员置空,因为是第一次插入嘛,所以后面必定为NULL

	}
	else
	{
		while( linkList->next && i < position-1)					//移动头指针到position的结点位置中
		{
			i++;									
			linkList = linkList->next;
		}
		
		if (DEBUG)
		{
			printf("开始初始化新添加的元素的值\n");
		}
	
		new_node->student = new_student;						//初始化链表节点的student成员
		strcpy( new_node->student->name ,node.name );					//初始化链表节点中的student成员中的name成员	
		new_node->student->age = node.age;						//初始化锭表节点中的student成员中的age成员
						

		new_node->length = count++;							//标识是第count次插入的数据

		new_node->next = linkList->next;						//将新添加的节点的下个成员指向前一个节点的next成员
		linkList->next = new_node;							//然后将前一个节点的next成员指向新添加的节点
	}

	linkList = head;									//重置链表的指针为头指针
	flag = 1;										//标识为成功插入
	return flag;										//返回结果标识
}

int linkListLength(struct list * linkList)							
{
	int length = 0;										//统计链表的长度
	struct list * head = linkList;								//声明一个链表指针使其指向链表的头指针
	while( linkList->next )									//统计长度(不包括头指针)
	{
		length++;
		linkList = linkList->next;
	}
	linkList = head;									//重置链表的头指针
	return length;										//返回求得的链表的长度
}

void showLinkList(struct list * linkList, int length)
{
	struct list * head = linkList;								//声明一个指向当前链表头结点的指针
	if ( length <= 0 )									//判断链表中是否有数据
	{
		printf("链表中没有数据!\n");
		return;
	}
	else
	{
		printf("链表中的成员个数为%d\n", length);
	}

	if (DEBUG)
	{
		printf("开始打印\n");	
	}

	while( head->next )									//开始打印链表结点的值
	{
		printf("length is %d\n", head->next->length);
		printf("student's name is %s, student's age is %d\n", head->next->student->name, head->next->student->age);
		head = head->next;
	}
	

}

这个是自己写的单向链表,不知道有没有什么问题,如有发现问题请告诉一下,呵呵.第一次写.

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值