线性表链式存储

思路就是用 结构体 包含 结构体,被包含的 结构体 是一个指针  指向下一个节点的地址,**重点在于这个指针一定要在结构体的最前面**,因为涉及到偏移量的问题


首先是头文件:

#ifndef __NODELIST_H__
#define __NODELIST_H__

#include "stdio.h"
#include "stdlib.h"

typedef void NodeList;
typedef struct _tag_NodeListNode  //单个节点
{
	struct _tag_NodeListNode * next;
}NodeListNode;

NodeList * NodeList_Create();//链表创建

void NodeList_Destroy(NodeList * list); //销毁链表

void NodeList_Clear(NodeList * list);//清空链表

int NodeList_Length(NodeList *list);//获取链表长度

int NodeList_insert(NodeList *list, NodeListNode *node, int pos);//插入节点

NodeList *NodeList_Get(NodeList *list, int pos);//获取链表中的元素

NodeList *NodeList_Delete(NodeList *list, int pos);//删除节点


#endif

然后是函数实现:

#include "nodelist.h"  

typedef struct TNodeList
{
	NodeListNode header;   //和老师类一样,一定要放在第一位,偏移量的问题,  header的地址就是链表最前面那个头的地址
	int length;//链表的长度
	
};

NodeList * NodeList_Create()//链表创建
{
	TNodeList *list = NULL;
	list = (TNodeList *)malloc(sizeof(TNodeList));
	if (list == NULL)
	{
		printf("ERROR!! FUNC NodeList_Create()  申请内存失败\n");
		return NULL;
	}

	list->length = 0;
	list->header.next = NULL;//初始化

	return list;
}
void NodeList_Destroy(NodeList * list) //销毁链表
{
	TNodeList *tlist = NULL;
	tlist = (TNodeList *)list;
	if (tlist != NULL)
	{
		free(list);
	}
	return;
}

void NodeList_Clear(NodeList * list)//清空链表
{
	TNodeList *tlist = NULL;
	tlist = (TNodeList *)list;
	if (tlist == NULL)
	{
		return;
	}
	tlist->length = 0;
	tlist->header.next = NULL;
	
	return;
}

int NodeList_Length(NodeList *list)//获取链表长度
{
	TNodeList *tlist = NULL;
	tlist = (TNodeList *)list;
	if (tlist == NULL)
	{
		return -1;
	}
	return tlist->length;
}

int NodeList_insert(NodeList *list, NodeListNode *node, int pos)//插入节点
{
	int ret = 0;
	
	if (list == NULL || node == NULL || pos < 0)
	{
		ret = -3;
		return ret;
	}

	TNodeList *tlist = NULL;
	tlist = (TNodeList *)list;
	if (tlist == NULL)
	{
		ret = -1;
		return ret;
	}

	NodeListNode *current = NULL;
	current = (NodeListNode *)list;
	if (current == NULL)
	{
		ret = -2;
		return ret;
	}
	
	if (pos > NodeList_Length(list))
	{
		ret = -4;
		return ret;
	}

	for (int i = 0; i < pos ; i++)
	{
		current = current->next;
	}

	node->next = current->next;
	current->next = node;
	tlist->length++;
	
	return ret;
}

NodeList *NodeList_Get(NodeList *list, int pos)//获取链表中的元素
{
	if (list == NULL || pos < 0)
	{
		return NULL;
	}

	TNodeList *tlist = NULL;
	tlist = (TNodeList *)list;
	if (tlist == NULL)
	{
		return NULL;
	}
	
	if (pos >= NodeList_Length(list))
	{
		return NULL;
	}

	NodeListNode *current = NULL;
	current = (NodeListNode *)list;
	if (current == NULL)
	{
		return NULL;
	}

	for (int i = 0; i < pos; i++)
	{
		current = current->next;
	}

	return (NodeList *)(current->next);

}
NodeList *NodeList_Delete(NodeList *list, int pos)//删除节点
{
	if (list == NULL || pos < 0)
	{
		return NULL;
	}

	TNodeList *tlist = NULL;
	tlist = (TNodeList *)list;
	if (tlist == NULL)
	{
		return NULL;
	}

	if (pos >= NodeList_Length(list))
	{
		return NULL;
	}

	NodeListNode *current = NULL;
	current = (NodeListNode *)list;
	if (current == NULL)
	{
		return NULL;
	}

	for (int i = 0; i < pos; i++)
	{
		current = current->next;
	}

	NodeListNode *last = NULL;
	last = current->next;
	current->next = last->next;

	tlist->length--;

	return (NodeList *)last;

}

最后是测试案例:

#include "nodelist.h"
typedef struct Teacher
{
	NodeListNode  node;  //任何结构体都可以包含这个节点,然后就可以把这个结构体插入到链表中,插入函数中传递的其实就是node的地址
	int age;
}Teacher;
void main()
{
	int ret = 0;
	Teacher t1, t2, t3, t4;
	t1.age = 1;
	t2.age = 2;
	t3.age = 3;
	t4.age = 4;
	NodeList *list = NULL;
	list = NodeList_Create();
	if (list == NULL)
	{
		printf("ERROR!! FUNC NodeList_Create()\n");
		goto END;
	}

	int length = NodeList_Length(list);
	printf("未插入数据时长度:%d\n", length);



	ret = NodeList_insert(list, (NodeListNode *)(&t1), 0);
	if (ret != 0)
	{
		printf("ERROR!! FUNC NodeList_insert()%d\n",ret);
		goto END;
	}
	ret = NodeList_insert(list, (NodeListNode *)(&t2), 0);
	if (ret != 0)
	{
		printf("ERROR!! FUNC NodeList_insert()%d\n", ret);
		goto END;
	}
	ret = NodeList_insert(list, (NodeListNode *)(&t3), 0);
	if (ret != 0)
	{
		printf("ERROR!! FUNC NodeList_insert()%d\n", ret);
		goto END;
	}
	ret = NodeList_insert(list, (NodeListNode *)(&t4), 0);
	if (ret != 0)
	{
		printf("ERROR!! FUNC NodeList_insert()%d\n", ret);
		goto END;
	}

	length = NodeList_Length(list);
	printf("插入数据后长度:%d\n", length);

	Teacher *tmp = NULL;
	tmp = (Teacher *) NodeList_Delete(list, 0);
	if (tmp == NULL)
	{
		printf("ERROR!! FUNC NodeList_Delete()\n");
		goto END;
	}
	printf("删除的老师的年龄:%d\n", tmp->age);

	length = NodeList_Length(list);
	printf("删除数据后长度:%d\n", length);


	tmp = (Teacher *)NodeList_Get(list, 0);
	if (tmp == NULL)
	{
		printf("ERROR!! FUNC NodeList_Delete()\n");
		goto END;
	}
	printf("获取第一个老师的年龄:%d\n", tmp->age);


	while (NodeList_Length(list) > 0)
	{
		tmp = (Teacher *)NodeList_Delete(list, 0);
		if (tmp == NULL)
		{
			printf("ERROR!! FUNC NodeList_Delete()\n");
			goto END;
		}
		printf("删除的老师的年龄:%d\n", tmp->age);
	}

	NodeList_Clear(list);
	NodeList_Destroy(list);





END:
	system("pause");
}













NodeList * NodeList_Create();//链表创建

void NodeList_Destroy(NodeList * list); //销毁链表

void NodeList_Clear(NodeList * list);//清空链表

int NodeList_Length(NodeList *list);//获取链表长度

int NodeList_insert(NodeList *list, NodeListNode *node, int pos);//插入节点

NodeList *NodeList_Get(NodeList *list, int pos);//获取链表中的元素

NodeList *NodeList_Delete(NodeList *list, int pos);//删除节点


  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
C语言中的线性表可以使用链式存储结构来实现。链式存储结构是通过节点之间的指针连接来表示数据元素之间的逻辑关系。 在链式存储结构中,每个节点包含两部分信息:数据域和指针域。数据域用于存储具体的数据元素,而指针域用于指向下一个节点的地址。 链表的头节点是链表的入口,通过头节点可以找到整个链表链表的最后一个节点的指针域为空,表示链表的结束。 以下是C语言中线性表链式存储的一般实现方式: ```c // 定义链表节点结构 typedef struct Node { int data; // 数据域 struct Node* next; // 指针域,指向下一个节点 } Node; // 初始化链表 void initList(Node** head) { *head = NULL; // 头节点为空 } // 在链表末尾插入元素 void insert(Node** head, int value) { Node* newNode = (Node*)malloc(sizeof(Node)); // 创建新节点 newNode->data = value; newNode->next = NULL; if (*head == NULL) { *head = newNode; // 如果链表为空,新节点为头节点 } else { Node* temp = *head; while (temp->next != NULL) { temp = temp->next; // 找到链表的最后一个节点 } temp->next = newNode; // 将新节点插入到最后一个节点的后面 } } // 遍历链表并打印元素 void printList(Node* head) { Node* temp = head; while (temp != NULL) { printf("%d ", temp->data); temp = temp->next; } printf("\n"); } ``` 这是一个简单的链表实现,你可以通过调用`initList`函数初始化链表,使用`insert`函数在链表末尾插入元素,使用`printList`函数遍历链表并打印元素。

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值