单向链表的基本操作

//LinkList.h
#pragma once
#include <stdio.h>
#include <stddef.h>
#include <Windows.h>
#include <stdlib.h>

typedef char LinkType;

typedef struct LinkNode {
	LinkType data;
	struct LinkNode* next;
} LinkNode;


void LinkListInit(LinkNode** head);//初始化链表

LinkNode* LinkListPushBack(LinkNode** head, LinkType value);//尾插一个元素到链表中

void LinkListPopBack(LinkNode** head);//尾删一个元素

void LinkListPushFront(LinkNode** head, LinkType value);//头插一个元素

void LinkListPopFront(LinkNode** head);//头删一个元素

/**
* @brief 查找元素在链表中的位置
*
* @param head
* @param to_find 要查找的值
*
* @return 这个值对应的节点的地址
*/
LinkNode* LinkListFind(LinkNode* head, LinkType to_find);

void LinkListInsert(LinkNode** head, LinkNode* pos, LinkType value);//在pos之前插入元素

void LinkListInsertAfter(LinkNode** head, LinkNode* pos, LinkType value);//在pos之后插入元素

void LinkListErase(LinkNode** head, LinkNode* pos);//删除指定位置的元素

void LinkListErase2(LinkNode** head, LinkNode* pos);//删除指定位置的元素 O(1)

void LinkListRemove(LinkNode** head, LinkType to_delete);//删除指定值的元素

void LinkListRemoveAll(LinkNode** head, LinkType value);//指定值的所有元素都删掉.

/**
* @brief 判定链表为空
*
* @return 链表为空, 返回1, 否则返回0
*/
int LinkListEmpty(LinkNode* head);

size_t LinkListSize(LinkNode* head);//求链表的元素个数

//LinkList.c
#include "LinkList.h"

//初始化链表
void LinkListInit(LinkNode** head)
{
	if (head == NULL)
	{
		//非法操作
		return;
	}
	if (*head == NULL)
	{
		//空链表
		return;
	}
	*head = NULL;
	return;
}

LinkNode *LinkListCreateNode(LinkType value)
{
	LinkNode * new_node = (LinkNode *)malloc(sizeof(LinkNode));
	new_node->data = value;
	new_node->next = NULL;
	return new_node;
}

void LinkListDestoryNode(LinkNode *to_delete)
{
	free(to_delete);
}

//尾插一个元素到链表中
LinkNode* LinkListPushBack(LinkNode** head, LinkType value)
{
	if (head == NULL)
	{
		//非法操作
		return NULL;
	}
	if (*head == NULL)
	{
		//空链表
		*head = LinkListCreateNode(value);
		return *head;
	}
	LinkNode *cur = *head;
	while (cur->next != NULL)
	{
		cur = cur->next;
	}
	cur->next = LinkListCreateNode(value);
	return cur->next;
}

//尾删一个元素
void LinkListPopBack(LinkNode** head)
{
	if (head == NULL || *head == NULL)
	{
		return;
	}
	if ((*head)->next == NULL)
	{
		//只有一个节点
		LinkNode *to_delete = *head;
		*head = NULL;
		LinkListDestoryNode(to_delete);
		return;
	}
	LinkNode *cur = *head;
	while (cur->next != NULL)
	{
		if (cur->next->next == NULL)
		{
			LinkNode *to_delete = cur->next;
			cur->next = to_delete->next;
			LinkListDestoryNode(to_delete);
			return;
		}
		cur = cur->next;
	}
	return;
}

//头插一个元素
void LinkListPushFront(LinkNode** head, LinkType value)
{
	if (head == NULL)
	{
		return;
	}
	if (*head == NULL)
	{
		LinkListPushBack(head, value);
		return;
	}
	LinkNode *cur = *head;
	cur = LinkListCreateNode(value);
	cur->next = *head;
	*head = cur;
	return;
}

//头删一个元素
void LinkListPopFront(LinkNode** head)
{
	if (head == NULL || *head == NULL)
	{
		return;
	}
	if ((*head)->next == NULL)
	{
		//只有一个节点
		LinkListPopBack(head);
		return;
	}
	LinkNode *cur = *head;
	*head = cur->next;
	LinkListDestoryNode(cur);
}

LinkNode* LinkListFind(LinkNode* head, LinkType to_find)
{
	if (head == NULL)
	{
		return NULL;
	}
	LinkNode *cur = head;
	if (cur->data == to_find)
	{
		//只有一个节点的时候
		return cur;
	}
	while (cur->next != NULL)
	{
		if (cur->data == to_find)
		{
			return cur;
		}
		cur = cur->next;
	}
	return NULL;
}

//在pos之前插入元素
void LinkListInsert(LinkNode** head, LinkNode* pos, LinkType value)
{
	if (head == NULL || *head == NULL)
	{
		return;
	}
	if (pos == NULL)
	{//如果pos==NULL 就尾插一个元素
		LinkListPushBack(head, value);
		return;
	}
	if ((*head)->next == NULL)
	{//如果只有一个元素并且第一个元素为pos的值,就头插一个元素
		if (pos == *head)
		{
			LinkListPushFront(head, value);
			return;
		}
		return;
	}
	LinkNode* cur = *head;
	while (cur->next != NULL)
	{
		if (cur->next == pos)
		{
			LinkNode * new_node = LinkListCreateNode(value);
			new_node->next = cur->next;
			cur->next = new_node;
			return;
		}
		cur = cur->next;
	}
}

//在pos之后插入元素
void LinkListInsertAfter(LinkNode** head, LinkNode* pos, LinkType value)
{
	if (head == NULL || *head == NULL || pos == NULL)
	{
		return;
	}
	LinkNode* cur = *head;
	while (cur != NULL)
	{
		if (cur == pos)
		{
			LinkNode* new_node = LinkListCreateNode(value);
			new_node->next = cur->next;
			cur->next = new_node;
			return;
		}
		cur = cur->next;
	}
	return;
}

//删除指定位置的元素
void LinkListErase(LinkNode** head, LinkNode* pos)
{
	if (head == NULL || *head == NULL)
	{
		return;
	}
	LinkNode *cur = *head;
	if (pos == *head)
	{
		LinkListPopFront(head);
		return;
	}
	while (cur->next != NULL)
	{
		if (cur->next == pos)
		{
			LinkNode* to_delete = cur->next;
			cur->next = to_delete->next;
			LinkListDestoryNode(to_delete);
		}
		cur = cur->next;
	}
	return;
}

//删除指定位置的元素 O(1)
void LinkListErase2(LinkNode** head, LinkNode* pos)
{
	if (head == NULL || *head == NULL || pos == NULL)
	{//非法操作          空链表            空指针
		return;
	}
	LinkNode *cur = *head;
	if (cur->next == NULL)
	{//如果链表只有一个元素
		if (cur = pos)
			LinkListPopBack(head);
		return;
	}
	if (pos->next == NULL)
	{//如果pos是最后一个元素
		if (cur = pos)
			LinkListPopBack(head);
		return;
	}
	pos->data = pos->next->data;
	LinkNode *to_delete = pos->next;
	pos->next = pos->next->next;
	LinkListDestoryNode(to_delete);

}

//删除指定值的元素
void LinkListRemove(LinkNode** head, LinkType to_delete)
{
	if (head == NULL || *head == NULL)
	{
		return;
	}
	LinkNode* cur = *head;
	if (cur->next == NULL)
	{//只有一个节点
		if (cur->data == to_delete)
		{
			*head = NULL;
			LinkListDestoryNode(cur);
		}
		return;
	}
	while (cur->next != NULL)
	{
		if (cur->next->data == to_delete)
		{//找到要删除的节点
			LinkNode* deletenode = cur->next;
			cur->next = deletenode->next;
			LinkListDestoryNode(deletenode);
		}
		cur = cur->next;
	}
	//没有找到节点
	return;
}

//指定值的所有元素都删掉.
void LinkListRemoveAll(LinkNode** head, LinkType value)
{
	if (head == NULL || *head == NULL)
	{
		return;
	}
	LinkNode *cur = *head;
	if (cur->next == NULL)
	{
		if (cur->data == value)
			LinkListPopBack(head);
		return;
	}
	while (cur->next != NULL)
	{
		if (cur->data == value)
			LinkListErase2(head, cur);
		else
			cur = cur->next;
	}
	return;
 }

//判断链表是否为空
int LinkListEmpty(LinkNode* head)
{
	if (head == NULL)
		return 1;
	return 0;
}

//求链表的元素个数
size_t LinkListSize(LinkNode* head)
{
	if (head == NULL)
	{
		return 0;
	}
	size_t count = 1;
	LinkNode *cur = head;
	while (cur->next != NULL)
	{
		cur = cur->next;
		count++;
	}
	return count;
}

//test.c
#include "LinkList.h"
#define FUN_HEADER printf("\n==================%s==================\n",__FUNCTION__);

void LinkListPrintChar(LinkNode *head,char *ch)
{
	printf("[%s]  ", ch);
	LinkNode *cur = head;
	for (; cur != NULL; cur = cur->next)
	{
		printf("[%c:%p] -> ", cur->data, cur);
	}
	printf("[NULL]\n");
}

void TestInit()
{
	FUN_HEADER;
	LinkNode *head;
	LinkListInit(&head);
	LinkListPrintChar(head, "初始化链表");
}

void TestPushBack()
{
	FUN_HEADER;
	LinkNode *head;
	LinkListInit(&head);
	LinkListPushBack(&head, 'a');
	LinkListPushBack(&head, 'b');
	LinkListPushBack(&head, 'c');
	LinkListPushBack(&head, 'd');
	LinkListPushBack(&head, 'e');
	LinkListPrintChar(head, "尾插五个元素");
}

void TestPopBack()
{
	FUN_HEADER;
	LinkNode *head;
	LinkListInit(&head);
	LinkListPopBack(&head);
	LinkListPrintChar(head, "对空链表进行尾删");
	LinkListPushBack(&head, 'a');
	LinkListPopBack(&head);
	LinkListPrintChar(head, "对只有一个节点的链表进行尾删");
	LinkListPushBack(&head, 'a');
	LinkListPushBack(&head, 'b');
	LinkListPushBack(&head, 'c');
	LinkListPushBack(&head, 'd');
	LinkListPopBack(&head);
	LinkListPrintChar(head,"对链表进行尾删");
}

void TsetPushFront()
{
	FUN_HEADER;
	LinkNode *head;
	LinkListInit(&head);
	LinkListPushFront(&head, 'a');
	LinkListPushFront(&head, 'b');
	LinkListPushFront(&head, 'c');
	LinkListPushFront(&head, 'd');
	LinkListPrintChar(head, "头插四个元素");
}

void TestPopFront()
{
	FUN_HEADER;
	LinkNode *head;
	LinkListInit(&head);
	LinkListPushBack(&head, 'a');
	LinkListPushBack(&head, 'b');
	LinkListPushBack(&head, 'c');
	LinkListPushBack(&head, 'd');
	LinkListPrintChar(head, "尾插四个元素");
	LinkListPopFront(&head);
	LinkListPrintChar(head, "头删一个元素");
	LinkListPopFront(&head);
	LinkListPopFront(&head);
	LinkListPrintChar(head, "再头删两个元素");
}

void TestLinkListFind()
{
	FUN_HEADER;
	LinkNode *head;
	LinkListInit(&head);
	LinkListFind(head, 'a');
	LinkListPrintChar(head, "链表为空时查找");
	LinkListPushBack(&head, 'a');
	LinkNode * pos_b = LinkListPushBack(&head, 'b');
	LinkListPushBack(&head, 'c');
	LinkListPushBack(&head, 'd');
	LinkNode * pos = LinkListFind(head, 'b');
	printf("pos_b expect %p,actually %p\n", pos_b, pos);
	pos = LinkListFind(head, 'x');
	printf("pos_x expect NULL,actually %p\n", pos);
}

void TestInsert()
{
	FUN_HEADER;
	LinkNode* head;
	LinkListInit(&head);
	LinkListPushBack(&head, 'a');
	LinkListPrintChar(head, "尾插一个元素");
	LinkListInsert(&head, head, 'x');
	LinkListPrintChar(head, "在a前插入一个 x");

	LinkListPushBack(&head, 'b');
	LinkListPushBack(&head, 'c');
	LinkNode * pos_d = LinkListPushBack(&head, 'd');
	LinkListPrintChar(head, "尾再插三个元素");
	LinkListInsert(&head, pos_d, 'y');
	LinkListPrintChar(head, "在d前插入一个 y");
}

void TestInsertAfter()
{
	FUN_HEADER;
	LinkNode *head;
	LinkListInit(&head);
	LinkListPushBack(&head, 'a');
	LinkListInsertAfter(&head, head, 'y');
	LinkListPrintChar(head, "在a之后插入 y");
	LinkListPushBack(&head, 'b');
	LinkNode * pos_c = LinkListPushBack(&head, 'c');
	LinkListPushBack(&head, 'd');
	LinkListInsertAfter(&head, pos_c, 'x');
	LinkListPrintChar(head, "在c之后插入 x");
}

void TestErase()
{
	FUN_HEADER;
	LinkNode * head;
	LinkListInit(&head);
	LinkListPushBack(&head, 'a');
	LinkListPushBack(&head, 'b');
	LinkNode* pos_c = LinkListPushBack(&head, 'c');
	LinkListPushBack(&head, 'd');
	LinkListPrintChar(head, "尾插四个元素");
	LinkListErase(&head,head);
	LinkListPrintChar(head, "删除头结点");
	LinkListErase(&head, pos_c);
	LinkListPrintChar(head, "删除c节点");
}

void TetsErase2()
{
	FUN_HEADER;
	LinkNode * head;
	LinkListInit(&head);
	LinkListPushBack(&head, 'a');
	LinkListPushBack(&head, 'b');
	LinkNode* pos_c = LinkListPushBack(&head, 'c');
	LinkListPushBack(&head, 'd');
	LinkListPrintChar(head, "尾插四个元素");
	LinkListErase2(&head, head);
	LinkListPrintChar(head, "删除头结点");
	LinkListErase2(&head, pos_c);
	LinkListPrintChar(head, "删除c节点");
	LinkListErase2(&head, pos_c);
	LinkListPrintChar(head, "删除最后一个节点d");
}

void TestRemove()
{
	FUN_HEADER;
	LinkNode* head;
	LinkListInit(&head);
	LinkListPushBack(&head, 'a');
	LinkListPrintChar(head, "尾插一个元素");
	LinkListRemove(&head, 'x');
	LinkListPrintChar(head, "删除不存在的元素x");
	LinkListRemove(&head, 'a');
	LinkListPrintChar(head, "链表只有一个元素a,删除a");
	LinkListPushBack(&head, 'a');
	LinkListPushBack(&head, 'b');
	LinkListPushBack(&head, 'c');
	LinkListPushBack(&head, 'c');
	LinkListPushBack(&head, 'd');
	LinkListPrintChar(head, "尾插五个元素");
	LinkListRemove(&head, 'x');
	LinkListPrintChar(head, "删除不存在的元素x");
	LinkListRemove(&head, 'c');
	LinkListPrintChar(head, "删除存在的元素c,如果重复,只删除第一个");
}


void TestRemoveAll()
{
	FUN_HEADER;
	LinkNode * head;
	LinkListInit(&head);
	LinkListPushBack(&head, 'a');
	LinkListPushBack(&head, 'c');
	LinkListPushBack(&head, 'c');
	LinkListPushBack(&head, 'b');
	LinkListPushBack(&head, 'c');
	LinkListPushBack(&head, 'd');
	LinkListPrintChar(head, "尾插六个元素");
	LinkListRemoveAll(&head, 'c');
	LinkListPrintChar(head, "删除所有的c");
}

void TestEmpty()
{
	FUN_HEADER;
	LinkNode * head;
	LinkListInit(&head);
	int ret = LinkListEmpty(head);
	printf("expect 1,actully %d\n", ret);
	LinkListPushBack(&head, 'a');

	ret = LinkListEmpty(head);
	printf("expect 0,actully %d\n", ret);
}

void TestLinkSize()
{
	FUN_HEADER;
	LinkNode * head;
	LinkListInit(&head);
	size_t size = LinkListSize(head);
	printf("expect 0,actully %lu\n", size);
	LinkListPushBack(&head, 'a');
	LinkListPushBack(&head, 'a');
	LinkListPushBack(&head, 'a');
	LinkListPushBack(&head, 'a');
	LinkListPushBack(&head, 'a');
	size = LinkListSize(head);
	printf("expect 5,actully %lu\n", size);
}

int main()
{
	TestInit();
	TestPushBack();
	TestPopBack();
	TsetPushFront();
	TestPopFront();
	TestLinkListFind();
	TestInsert();
	TestInsertAfter();
	TestErase();
	TetsErase2();
	TestRemove();
	TestRemoveAll();
	TestEmpty();
	TestLinkSize();
        system("pause");
	return 0;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值