数据结构——链表

本文所讲的链表是单链表,链表采用无头链表

科普下:一般链表可以分为有头节点的链表与无头节点的链表, 

有头节点的链表:每个节点存储这个一个或者一组数据,但是有头节点的链表的第一个节点是头节点,头节点只是一个节点,但不存储数据,头节点的主要作用是方便插入操作

无头节点的链表:每个节点都是有效节点,都存储有效的数据

至于为什么用无头节点,是因为刚实习的时候被领导说了使用有头节点的链表是浪费内存,好吧!!

(1)定义链表结构

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

typedef struct {
	char key[15];
	char name[20];
	int age;
} DATA;

typedef struct Node {
	DATA data;
	struct Node *next;
} ChainListType;

(2)定义链表操作

ChainListType *ChainListAddEnd(ChainListType *head, DATA data); //添加节点到链表末尾
ChainListType *ChainListAddFirst(ChainListType *head, DATA data); //添加节点到链表首部
ChainListType *ChainListFind(ChainListType *head, char *key); //按关键字在链表中查找内容
ChainListType *ChainListInsert(ChainListType *head, char *findkey, DATA data); //插入节点到指定位置
int ChainListDelete(ChainListType *head, char *key); //删除指定关键字的节点
int ChainListLength(ChainListType *head); //获取链表节点数量

(3)链表操作

/*
 * 添加节点到链表末尾
 * */
ChainListType *ChainListAddEnd(ChainListType *head, DATA data)
{
	ChainListType *node, *h;
	if (!(node = (ChainListType *)malloc(sizeof(ChainListType)))) {
		printf("为保存节点数据申请内存失败!\n");
		return NULL;
	}

	node->data = data;
	node->next = NULL;

	if (head == NULL) {
		head = node;
		return head;
	}

	h = head;

	while (h->next != NULL) {
		h = h->next;
	}

	h->next = node;
	return head;
}

/*
 * 添加节点到链表首部
 * */
ChainListType *ChainListAddFirst(ChainListType *head, DATA data)
{
	ChainListType *node;
	if (!(node = (ChainListType *)malloc(sizeof(ChainListType)))) {
		printf("为保存节点数据申请内存失败!\n");
		return NULL;
	}

	node->data = data;
	node->next = head;
	head = node;

	return head;
}

/*
 * 按关键字在链表中查找内容
 * */
ChainListType *ChainListFind(ChainListType *head, char *key)
{
	ChainListType *h;

	h = head;
	while (h) {
		if (strcmp(h->data.key, key) == 0)
			return h;
		h = h->next;
	}
	return NULL;
}

/*
 * 插入节点到指定位置
 * */
ChainListType *ChainListInsert(ChainListType *head, char *findkey, DATA data)
{
	ChainListType *node, *node1;
	if (!(node = (ChainListType *)malloc(sizeof(ChainListType)))) {
		printf("为保存节点数据申请内存失败!\n");
		return NULL;
	}

	node->data= data;
	node1 = ChainListFind(head, findkey);
	if (node1) {
		node->next = node1->next;
		node1->next = node;
	} else {
		printf("未找到插入节点!\n");
		free(node);
	}

	return head;
}

/*
 * 删除指定关键字的节点
 * */
int ChainListDelete(ChainListType *head, char *key)
{
	ChainListType *node, *h;

	h=head;
	while (h) {
		if (strcmp(h->data.key, key) == 0) {
			node = h->next; //无头节点的删除,将要删除的节点下个节点数据拷贝给删除节点,然后删除下一个节点
			h->data = node->data;  
			h->next = node->next;
			free(node);
			return 1;
		} else {
			h = h->next;
		}
	}
}

/*
 * 获取链表节点数量
 * */
int ChainListLength(ChainListType *head)
{
	ChainListType *h;
	int i = 0;

	while (h) {
		i++;
		h = h->next;
	}

	return i;
}

/*
 * 遍历链表
 * */
void ChainListAll(ChainListType *head)
{
	ChainListType *h;
	DATA data;
	h = head;
	printf("链表所有数据如下:\n");

	while (h) {
		data = h->data;
		printf("(%s,%s,%d)\n", data.key, data.name, data.age);
		h = h->next;
	}
	return;
}

 

转载于:https://my.oschina.net/wangande2014/blog/684291

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值