肥猫学习日记---数据结构与算法(三)-----链表

什么是链表

由一系列结点(链表中每一个元素称为结点)组成的一个有方向的数据结构体叫链表。其逻辑顺序由指针链接次序实现的

顺序链表

就我个人认为,顺序链表就是单项链表,即每个节点只有一个指针指向下一个节点。

顺序链表的创建

要想创建一个链表,我们需要先创建其中的节点

#define TYPE int
typedef struct Node
{
	TYPE* data;//数据域
	struct Node* next; //指针域
} Node;

Node* creat_node(data)
{
	Node* node = malloc(sizeof(Node));
	node->data = data;
	node->next = NULL;
	return node;
}

然后就可以创建链表了

typedef struct List
{
	Node* head;//头指针
	Node* tail;//尾指针
	size_t size; //链表长度
}List;

List* creat_list()
{
	List* list = malloc(sizeof(List));
	list->head = NULL;
	list->tail = NULL;
	list->size = 0;
	return list;
}

链表的操作(增删查改)

链表头添加

先看代码

void add_head(List* list,TYPE data)
{
	Node* node = creat_node(data);//创建一个新的结点
	if(0 == list->size)
	{
		list->head = node;
		list->tail = node;
	}
	else
	{
		node->next = list->head;//新结点指向头指针所指的位子
		list->head = node;//头指针移动到新新节点
	}
	list->size++;//链表长度+1
}

头指针指向的本来结点1前面是NULL,现在结点1的前面多了一个node结点,就是头添加。

尾添加

与头添加差别不大

void add_tail(List* list,TYPE data)
{
	if(0 == list->size) add_head(list,data);
	Node* node = creat_node(list, data);
	list->tail->next = node;
	list->tail = node;
	list->size++;
}

头删除

bool del_head(List* list)
{
	if(0 == list->size) return false;
	if(1 == lsit ->size)
	{
		list->tail =NULL;//只有一个结点的话就将尾指针置空,无法访问到该节点,就相当于删除
	}
	Node* node = list->head;//node相当于第一个结点
	list->head = node->next;//把头指针指向第一个结点的下一个
	free(node);//释放第一个结点,就相当于头删除
	list->size--;
	return true;
}

尾删除

参考尾添加与头删除

bool del_tail(List* list)
{
	if(0 == list->size) return false;
	if(1 == list->size) del_head(list);
	Node* prev = list->head;
	for(int i = 0 ; i<list->size;i++)
	{
		prev= prev->next;
	}
	free(list->tail);
	prev->next = NULL;
	list->tail = prev;
	list->size--;
	return true;
}

插入

由于这次介绍的链表是单向的,为了要在一个位置插入一个新的结点,我们需要找到这个位置结点的前一个结点

bool insert_list(List* list,int index,TYPE data)
{
	if(index <0 || index >=list->size)return false;
	//如果插入位子比0小,比整个链表长度大,我们就返回错误
	if(0 == index) //在0位置插入就等于加了一个头结点
	{
		add_head(list,data);
		return true;
		}
	Node* node = creat_node(data);
	Node* prev = list->head;
	foe(int i = 0; i <index;i++)
	{
		prev= prev->next;//找到要插入位置的前一个结点
	}
	node->next = prev->next;//prev的下一个结点就是我们要插入的位置,将node结点指向这个结点
	prev->next = node;//prev指向node结点
	list->size++;
	return true;
}

位置删除

bool delete_index_list(List* list,int index)
{
	if(index<0 || index >= list->size) return false;
	if(0 == index)
	{
		del_head(list);//只有一个结点就相当于删除头结点
	}
	else if(list->size == index+1)
	{
		del_tail(list);//同上
	}
	else
	{
		Node prev = list->head;
		for(int i = 0 ; i<index;i++)
		{
			prev= prev->next;//找到要删除结点的前一个
		}
		Node* node = prev->next;//node相当于要删除的结点
		prev->next = node->next;//要删除的结点的前一个结点指向要删除的结点的下一个结点
		free(node);
		list->size--;
		return true;
	}
}

值删除

与位置删除核心思想相同,略微做出改变即可

bool del_data_list(List* list,TYPE data)
{
	if(data = list->head->data)
	{
		del_head(list);
		return true;
	}
	Node* prev =list->head; 
	while(NULL != prev->next)
	{
		if(prev->next->data == data)
		{
			Node* node = prev->next;
			prev->next = node->next;
			free(node);
			list->size--;
			return true;
		}
		prev=prev->next;
	}
	return false;
}

排序

我们用冒泡排序来对链表进行排序

void sort_list(List* list)
{
	for(Node* i = list->head; NULL!=i->next;i=i->next)
	{
		for(Node* j = i->next;NULL != j;j=j->next)
		{
			if(i->data > j ->data)
			{
				TYPE temp = i->data;
				i->data = j ->data;
				j->data = temp;
			}
		}	
	}
}

遍历

相对之前难理解得地方而言,这个相对简单

void show_list(List* list)
{
	for(Node* i = list->head;NULL != i->next;i=i->next)
	{
		printf("%d ",i->data);
	}
	printf("\n");
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值