数据结构——链表1

数据结构——链表 1

数据结构——链表1

//链表结点数据类型
struct linknode
{
	void * data;
	struct linknode *next;
};
//链表数据类型
//记录链表信息,链表头结点,大小等信息
struct linklist
{
	struct linknode header;//拿到链表的头结点就相当于拿到整个链表
	//也可以*header,但是这个时候要给header分配内存,略显麻烦
	int size;//链表的大小
};

说明:在定义结构体的头节点时,如果是个指针类型,比如struct linknode *header;
那么必须在下面malloc必要的内存空间,(在struct linknode里面也是指针类型,一次还要多次malloc出内存空间)为了方便起见这里不用指针类型。

链表的初始化操作

void* Init_list()
{
	struct linklist *list = malloc(sizeof(struct linklist));
	if(list == NULL)
	{
		return NULL;
	}
	list->header.next = NULL;//初始化链表时只有一个头结点,其余为空
}

链表的插入操作
TIP:如果完成插入操作,必须找到插入节点的前一个位置。

编程核心思路:①首先找到要插入节点的前一个节点,利用for循环来实现。②需要一个当前指针,来记录这个节点struct linknode *current = &(mylist->header);之所以这样,就可以在for循环中用current = current->next;(我更喜欢叫这个为“代理人战争”,header毕竟是“带头大哥”不能亲自出马,哈哈~皮一下)。③接着,需要newnode节点,完成插入操作
代码实现如下:

//插入节点
void insert_link(void *list,int pos,void* data)
{
	int i = 0;
	struct linklist *mylist = (struct linklist *)list;
	struct linknode *current = &(mylist->header);
	struct linknode *newnode = malloc(sizeof(struct linknode));
	newnode->data  = data;
	newnode->next = NULL;
	if(list == NULL)
	{
		return;
	}
	if(data ==NULL)
	{
		return;
	}
	if(pos < 0 || pos > mylist->size-1)
	{
		pos = mylist->size;
	}
	//找到要插入的位置,利用for循环
	for(i = 0;i<pos;i++)
	{
		current = current->next;
	}
	newnode->next = current->next;
	current->next = newnode;
	mylist->size++;//记录节点个数
}

遍历节点
编程核心思考:①采用回调函数的方式打印出数据。②因为要传入链表,传入节点所以定义如下struct linklist *mylist = (struct linklist *)list; struct linknode *current = mylist->header.next ;
实现代码如下:

//遍历链表
void Foreach_linklist(void *list,void(*reback)(void *))
{

	struct linklist *mylist = (struct linklist *)list;
	struct linknode *current = mylist->header.next ;
	if(list == NULL)
	{
		return;
	}
	while(current != NULL)
	{	
		reback(current->data);
		current = current->next;	
		
	}
}

下面贴出全部的代码,经过测试的,代码比较长,得耐心看。

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


/**************************************************
*特点:链表包含两个域数据域和指针域
*      链表访问时单线访问的
*	   链表由一系列节点组成,数据域保存用户数据
*	   指针域保存下一个节点的地址
*	   链表在内存中是非连续的
***************************************************/
//==========测试数据=============================
struct person
{
	char name[30];
	int age;
};
//==============================================
//链表结点数据类型
struct linknode
{
	void * data;
	struct linknode *next;
};
//链表数据类型
//记录链表信息,链表头结点,大小等信息
struct linklist
{
	struct linknode header;//拿到链表的头结点就相当于拿到整个链表
	//也可以*header,但是这个时候要给header分配内存,略显麻烦
	int size;//链表的大小
};

//初始化链表
typedef void *LList;

void* Init_list()
{
	struct linklist *list = malloc(sizeof(struct linklist));
	if(list == NULL)
	{
		return NULL;
	}
	list->header.next = NULL;
	list->size = 0;
	return list;
}
//插入节点
void insert_link(void *list,int pos,void* data)
{
	int i = 0;
	struct linklist *mylist = (struct linklist *)list;
	struct linknode *current = &(mylist->header);
	struct linknode *newnode = malloc(sizeof(struct linknode));
	newnode->data  = data;
	newnode->next = NULL;
	if(list == NULL)
	{
		return;
	}
	if(data ==NULL)
	{
		return;
	}
	if(pos < 0 || pos > mylist->size-1)
	{
		pos = mylist->size;
	}
	//找到要插入的位置,利用for循环
	for(i = 0;i<pos;i++)
	{
		current = current->next;
	}
	newnode->next = current->next;
	current->next = newnode;
	mylist->size++;
}
//打印函数
void print(void *data)
{
	struct person* data1 = (struct person*)data;
    printf("姓名:%s,年龄:%d\r\n",data1->name ,data1->age);
}
//遍历链表
void Foreach_linklist(void *list,void(*reback)(void *))
{

	struct linklist *mylist = (struct linklist *)list;
	struct linknode *current = mylist->header.next ;
	if(list == NULL)
	{
		return;
	}
	while(current != NULL)
	{	
		reback(current->data);
		current = current->next;	
		
	}
}
int main()
{
	int i;
	//创建一些数据便于测试
	struct person s1 = {"xioming",20};
	struct person s2 = {"xiaoli",23};	
	struct person s3 = {"xiaozhang",24};
	//创建一个链表
	struct linklist *list = NULL;
	list = Init_list();//初始化

	//插入链表
	insert_link(list,0,&s1);
	insert_link(list,0,&s2);
	insert_link(list,0,&s3);
	//遍历链表并打印
	Foreach_linklist(list,print);		
	return 0;
}
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值