数据结构链式线性表


数据结构链式线性表实现



/*****************************************************
  > File Name   : test.c
  > Author      : xboss
  > Mail        : 2366006417@qq.com 
  > Created Time: 2020年06月13日 星期六 15时14分59秒
 *****************************************************/

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


typedef void LinkList;

//小链表节点,需要上层去包含此节点例如
/*
typedef struct teacher_message
{
	LinkListNode node;    //让老师对象节点去包含小节点,并且老师节点地址和小链表地址相同,没有偏移量
	int age;
	char name[];
}Teacher;
*/
typedef struct _tag_LinkListNode
{
	struct _tag_LinkListNode *next;  
	
}LinkListNode;           //小链表节点,需要上层应用去包含此节点


typedef struct _tag_LinkList
{
	LinkListNode head;  //链表头部
	int length; 	    //链式线性表的当前的长度(到底有多少个子节点)
	
}TLinkList;

/***************************************
function :链式线性表创建
parameter:无
return   :链式线性表数据对象的首地址
****************************************/      
LinkList* LinkList_Create()
{
	TLinkList *tep = (TLinkList *)malloc(sizeof(LinkList));
//malloc后置0
	memset(tep,0,sizeof(LinkList));
	
	tep->length = 0;
	tep->head.next = NULL;
	return tep;
}

/***************************************
function :链式线性表销毁
parameter:链式线性表数据对象的首地址
return   :无
****************************************/
void LinkList_Destory(LinkList *list)
{
	if(list != NULL)
	{
		free(list);
		list = NULL;
	}
	return ;
}

/***************************************
function :链式线性表清除(让链表回到初始值)
parameter:链式线性表数据对象的首地址
return   :无
****************************************/
void LinkList_Clear(LinkList *list)
{
	TLinkList *tlist = NULL;
	if(list == NULL)
	{	
		return ;
	}
	tlist = (TLinkList *)list;
	tlist->length = 0;
	tlist->head.next = NULL;
	return ;
}

/***************************************
function :链式线性表长度计算
parameter:链式线性表数据对象的首地址
return   :链式线性表长度
****************************************/
int LinkList_Length(LinkList *list)
{
	TLinkList *tlist = NULL;
	if(list == NULL)
	{	
		return -1;
	}
	tlist = (TLinkList *)list;
	return tlist->length;
}

/***************************************
function :链式线性表数据插入
parameter:链式线性表数据对象的首地址,插入的链表子节点,插入的位置
return   :成功返回0,失败返回-1
****************************************/
int LinkList_Insert(LinkList *list,LinkListNode *node,int pos)
{
	int ret = 0,i= 0;
	TLinkList *tlist = NULL;
	LinkListNode *current = NULL; //辅助指针变量
	if(list == NULL || node == NULL || pos < 0 )
	{
		ret = -1;
		printf("LinkList_Insert err:%d\r\n",ret);
		return ret;	
	}
	tlist = (TLinkList *)list;
	current = &(tlist->head);                      //辅助指针指着链表头部
	
	for(i = 0;i<pos && current->next != NULL;i++)//让辅助指针跳到插入位置的前一个位置
	{
		current = current->next;
	}
	
	node->next = current->next;  //让node节点连接后续链表
	
	current->next = node;        //让前面的链表连接新的node节点
	
	tlist->length++;             //长度加1
	
	return 0;	 
}
 
/***************************************
function :获取链式线性表指定位置上的数据
parameter:链式线性表数据对象的首地址,获取的位置
return   :获取到数据位置的地址
****************************************/
LinkList* LinkList_Get(LinkList *list,int pos)
{
	int ret = 0,i= 0;
	TLinkList *tlist = NULL;
	LinkListNode *current = NULL; //辅助指针变量
	if(list == NULL || pos < 0 )
	{
		ret = -1;
		printf("LinkList_Insert err:%d\r\n",ret);
		return NULL;	
	}
	tlist = (TLinkList *)list;
	current = &(tlist->head);                      //辅助指针指着链表头部
	
	for(i = 0;i<pos && current->next != NULL;i++)//让辅助指针跳到插入位置的前一个位置
	{
		current = current->next;
	}
	return current->next;
}
 
/***************************************
function :链式线性表删除指定位置的数据
parameter:链式线性表数据对象的首地址,指定位置pos
return   :需要删除数据位置的地址
****************************************/
LinkList* LinkList_Delete(LinkList *list,int pos)
{
	int ret = 0,i= 0;
	TLinkList *tlist = NULL;
	LinkListNode *current = NULL; //辅助指针变量
	LinkListNode *tem = NULL;
	if(list == NULL || pos < 0 )
	{
		ret = -1;
		printf("LinkList_Insert err:%d\r\n",ret);
		return NULL;	
	}
	tlist = (TLinkList *)list;
	current = &(tlist->head);                      //辅助指针指着链表头部
	
	for(i = 0;i<pos && current->next != NULL;i++)//让辅助指针跳到插入位置的前一个位置
	{
		current = current->next;
	}
	
	tem = current->next;        //缓存被删除节点的位置
	current->next = tem->next;  //连接节点
	tlist->length--;           //长度减1
	return tem;
}



typedef struct teacher_message
{
	LinkListNode node;    //让老师对象节点去包含小节点,并且老师节点地址和小链表地址相同,没有偏移量
	int age;
	char name[64];
}Teacher;

int main(void)
{
	Teacher t1,t2,t3;
	int ret = 0;
	int i = 0;
	t1.age = 22;
	strcpy(t1.name,"黎明");//向name中拷贝字符串,只能通过strcpy函数完成
	t2.age = 13;
	strcpy(t2.name,"小刚学长");
	t3.age = 14;
	strcpy(t3.name,"小东");
	
	LinkList* list = NULL;
//创建顺序线性表
	list = LinkList_Create(); 
	if(list == NULL)
	{
		printf("LinkList_Create\r\n");
		exit(1);

	}
//向顺序线性表插入数据
	ret = LinkList_Insert(list,(LinkListNode *)&t1,0);
	ret = LinkList_Insert(list,(LinkListNode *)&t2,0);
	ret = LinkList_Insert(list,(LinkListNode *)&t3,0);
//遍历顺序线性表中的元素
	for(i = 0;i<LinkList_Length(list);i++)
	{
		Teacher *temp = (Teacher *)LinkList_Get(list,i);
		if(temp == NULL)
		{
			printf("error");
			exit(1);

		}
		printf("temp->age= %d\r\n",temp->age);
		printf("temp->name= %s\r\n",temp->name);

	}
//删除顺序线性表中的元素
	LinkList_Delete(list,0);
	Teacher *temp = (Teacher *)LinkList_Get(list,0);
	printf("temp->age= %d\r\n",temp->age);
	printf("temp->name= %s\r\n",temp->name);
	return 0;
	
}

1、代码运行效果

在这里插入图片描述

2、链表发展的过程(本文采用第三种,让子节点(例如本文的LinkListNode对象)和业务节点(上层应用的对象,例如本文的Teacher对象)在同一个地址,没有偏移量)

typedef struct teacher_message
{
	LinkListNode node;    //让老师对象节点去包含小节点,并且老师节点地址和小链表地址相同,没有偏移量
	int age;
	char name[64];
}Teacher;

在这里插入图片描述

3、插入节点示意图(算法中的 LinkList_Insert函数实现原理)

在这里插入图片描述

4、删除节点示意图(算法中的 LinkList_Delete函数实现原理)(使用两个辅助指针

在这里插入图片描述

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值