数据结构 关于单链表的基本操作

以下是有关单链表增删查改的一些代码:

linklist.h

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

#define TITLE printf("\n======================%s====================\n",__FUNCTION__);

typedef char LinkType;

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

LinkNode* CreateNode(LinkType value);  //创建结点
void DestroyNode(LinkNode* node); // 销毁结点 

void LinkListInit(pLinkNode* head);  //初始化 
void LinkListPrint(LinkNode* head,const char* msg );//打印
void LinkListPushBack(LinkNode** head,LinkType value);  //尾插
void LinkListPopBack(LinkNode **head);//尾删
void LinkListPushFront(LinkNode** head, LinkType value);  //头插 
void LinkListPopFront(LinkNode** head); //头删
LinkNode* LinkListFind(LinkNode* head, LinkType to_find);// 查找元素在链表中的位置,return 这个值对应的节点的地址
void LinkListInsert(LinkNode** head, LinkNode* pos, LinkType value); //指定位置前插入
void LinkListInsertAfter(LinkNode** head, LinkNode* pos, LinkType value);//指定位置后插入
void LinkListErase(LinkNode** head, LinkNode* pos);//删除指定位置元素
void LinkListRemove(LinkNode** head, LinkType to_delete);//删除指定元素
void LinkListRemoveAll(LinkNode** head, LinkType value); //删除指定值的所有元素
int LinkListEmpty(LinkNode* head); //判断链表是否为空,为空返回0,否则返回1
size_t LinkListSize(LinkNode* head);//求链表元素个数
void LinkListReversePrint(LinkNode* head);//逆序打印链表
void LinkListInsertBefore(LinkNode** head, LinkNode* pos, LinkType value);//不遍历链表在pos之前插入

linklist.c

#include "link.h"
#include <stdlib.h>

void LinkListInit(LinkNode** head)
{
	if(head == NULL)
	{
		return;
	}
	*head = NULL;
}


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

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

void DestroyNode(LinkNode* node)
{
	free(node);
}

void LinkListPushBack(LinkNode** head,LinkType value)
{
	if(head == NULL)
	{
		//非法参数
		return;
	}
	if(*head == NULL)
	{
		//当前是一个空链表,直接将元素插入到头结点
		*head = CreateNode(value);
		return;
	}
	LinkNode* cur = *head;
	while(cur->next!=NULL)
	{
		cur = cur->next;
	}
	LinkNode* new_node = CreateNode(value);
	cur->next = new_node;
	return;
}


void LinkListPopBack(LinkNode** head)
{
	if(head == NULL)
	{
		//非法输入
		return;
	}
	if(*head == NULL)
	{
		//空链表
		return;
	}
	LinkNode* cur = *head;
	if(cur->next == NULL)
	{
		DestroyNode(cur);
	}
	while(cur->next != NULL)
	{
		if(cur->next->next == NULL)
		{
			//找到倒数第二个结点
			LinkNode* to_erase = cur->next;
			cur->next = NULL;
			DestroyNode(to_erase);
		}
		else
		{
		cur = cur->next;
		}
	}
	return;
}

void LinkListPushFront(LinkNode** head, LinkType value)
{
	if(head == NULL)
	{
		return;
	}

	if(*head == NULL)
	{
		*head = CreateNode(value);
		return;
	}
	LinkNode* new_node = CreateNode(value);
	new_node->next = *head;
	*head = new_node;
	return;
}


void LinkListPopFront(LinkNode** head)
{
	if(head == NULL)
	{
		//非法输入
		return;
	}
	if(*head == NULL)
	{
		//空链表,不做任何事情直接返回
		return;
	}
	LinkNode* to_erase = *head;
	*head = (*head)->next;
	DestroyNode(to_erase);
}

LinkNode* LinkListFind(LinkNode* head, LinkType to_find)
{
	if(head == NULL)
	{
		//空链表
		return NULL;
	}
	LinkNode* cur = head;
	while(cur != NULL)
	{
		if(cur->data == to_find)
		{
			return cur;
		}
		cur = cur->next;
	}
	return NULL;
}

void LinkListInsert(LinkNode** head, LinkNode* pos, LinkType value)
{
	if(head == NULL)
	{
		//非法输入
		return;
	}
	if(*head == NULL)
	{
		*head = CreateNode(value);
		return;
	}
	if(*head == pos)
	{
		LinkListPushFront(head,value);
		return;
	}
	if(pos == NULL)
	{
		LinkListPushBack(head,value);
		return;
	}
	LinkNode* cur = *head;
	while(cur->next != NULL)
	{
		if(cur->next == pos)
		{
			LinkNode* new_node = CreateNode(value);
			cur->next = new_node;
			new_node->next = pos;
			return;
		}
		else
		{
			cur = cur->next;
		}
	}
	return;
}

void LinkListInsertAfter(LinkNode** head, LinkNode* pos, LinkType value)
{
	if(head == NULL)
	{
		//非法输入
		return;
	}
	if(*head == NULL)
	{
		LinkListPushBack(head,value);
		return;
	}
	if(pos->next == NULL)
	{
		LinkListPushBack(head,value);
		return;
	}
	if(pos == NULL)
	{
		return;
	}
	LinkNode* next = pos->next;
	LinkNode* new_node = CreateNode(value);
	pos->next = new_node;
	new_node->next = next;
	return;
}


void LinkListErase(LinkNode** head, LinkNode* pos)
{
	if(head == NULL)
	{
		//非法输入
		return;
	}
	if(*head == NULL)
	{
		//空链表
		return;
	}
	if(pos == NULL)
	{
		return;
	}
	LinkNode* cur = *head;
	while(cur != NULL)
	{
		if(cur->next == pos)
		{
			LinkNode* next = pos->next;
			cur->next = next;
			DestroyNode(pos);
			return;
		}
		else
		{
			cur = cur->next;
		}
	}
	return;
}
void LinkListRemove(LinkNode** head, LinkType to_delete)
{
	if(head == NULL)
	{
		//非法输入
		return;
	}
	if(*head == NULL)
	{
		//空链表
		return;
	}
	if((*head)->data == to_delete)
	{
		LinkNode* Delete = *head;
		*head = (*head)->next;
		DestroyNode(Delete);
		return;
	}
	LinkNode* cur = *head;
	while(cur != NULL)
	{
		if(cur->next->data == to_delete)
		{
			LinkNode* Delete = cur->next;
			LinkNode* next = cur->next->next;
			cur->next = next;
			DestroyNode(Delete);
			return;
		}
		else
		{
			cur = cur->next;
		}
	}
	return;
}

void LinkListRemoveAll(LinkNode** head, LinkType value)
{
	if(head == NULL)
	{
		//非法输入
		return;
	}
	if(*head == NULL)
	{
		//空链表
		return;
	}
	LinkNode *cur = *head;  
	while((*head)->data == value)
	{
	  	if(cur->data == value)
	  	{
	  		LinkNode* Delete = cur;
	  		*head = (*head)->next;
	  		cur = cur->next;
	  		DestroyNode(Delete);
		}
	}
	while(cur->next != NULL)
	{
		if(cur->data == value)
		{
			LinkListErase(head,cur);
		}
		cur = cur->next;
	}
	if(cur->data == value)
	{
		LinkListPopBack(head);
	}
}


int LinkListEmpty(LinkNode* head)
{
	if(head == NULL)
	{
		//空链表
		return 0;
	}
	else
	return 1;
}

size_t LinkListSize(LinkNode* head)
{
	if(head == NULL)
	{
		return 0;
	}
	size_t size = 0;
	LinkNode* cur = head;
	while(cur != NULL)
	{
		size++;
		cur = cur->next;
	}
	return size;
}

void LinkListReversePrint(LinkNode* head)
{
	if(head == NULL)
	{
	//	printf("[NULL]\n");
		return;
	}
	LinkListReversePrint(head->next);
	printf("[%c]  ",head->data);
}


void LinkListInsertBefore(LinkNode** head, LinkNode* pos, LinkType value)
{
	if(head == NULL)
	{
		//非法输入
		return;
	}
	if(*head == NULL)
	{
		*head = CreateNode(value);
		return;
	}
	if(pos == NULL)
	{
		return;
	}
	if(pos == *head)
	{
		LinkListPushFront(head,value);
		return;
	}
	LinkNode* new_node = CreateNode(pos->data);
	LinkNode* next = pos->next;
	pos->next = new_node;
	new_node->next = next;
	pos->data = value;
	return;
}

///
//	           以下为测试代码              //
//

void TestInit()
{
	TITLE;
	LinkNode* head;
	LinkListInit(&head);
	//printf("head=%p\n",head);
}

void TestLinkListPushBack()
{
	TITLE;
	LinkNode* head;
	LinkListInit(&head);
	LinkListPushBack(&head,'a');
	LinkListPushBack(&head,'b');
	LinkListPushBack(&head,'c');
	LinkListPushBack(&head,'d');
	LinkListPrint(head,"尾插4个元素");
}

void TestLinkListPopBack()
{	
	TITLE;
	LinkNode* head;
	LinkListInit(&head);
	LinkListPushBack(&head,'a');
	LinkListPushBack(&head,'b');
	LinkListPushBack(&head,'c');
	LinkListPushBack(&head,'d');
	LinkListPopBack(&head);
	LinkListPopBack(&head);
	LinkListPrint(head,"尾删2个元素");
}

void TestLinkListPushFront()
{
	TITLE;
	LinkNode* head;
	LinkListInit(&head);
	LinkListPushFront(&head,'a');
	LinkListPushFront(&head,'b');
	LinkListPushFront(&head,'c');
	LinkListPushFront(&head,'d');
	LinkListPrint(head,"头插4个元素");
}

void TestLinkListPopFront()
{
	
	TITLE;
	LinkNode* head;
	LinkListInit(&head);
	LinkListPushFront(&head,'a');
	LinkListPushFront(&head,'b');
	LinkListPushFront(&head,'c');
	LinkListPushFront(&head,'d');
	LinkListPopFront(&head);
	LinkListPopFront(&head);
	LinkListPrint(head,"头删2个元素");
	LinkListPopFront(&head);
	LinkListPopFront(&head);
	LinkListPrint(head,"再头删2个元素");
	LinkListPopFront(&head);
	LinkListPrint(head,"头删空链表");

}

void TestLinkListFind()
{
	
	TITLE;
	LinkNode* head;
	LinkListInit(&head);
	LinkListPushFront(&head,'a');
	LinkListPushFront(&head,'b');
	LinkListPushFront(&head,'c');
	LinkListPushFront(&head,'d');
	LinkListPrint(head,"查找元素");
	LinkNode* pos = LinkListFind(head,'x');
	printf("pos x expect NULL,pos actual %p\n",pos);
	pos = LinkListFind(head,'c');
	printf("pos actual %p\n",pos);
	
}

void TestLinkListInsert()
{
	
	TITLE;
	LinkNode* head;
	LinkListInit(&head);
	LinkListInsert(&head,head,'b');
	LinkListPrint(head,"对空链表进行插入");
	LinkListInsert(&head,head,'a');
	LinkListPrint(head,"对链表头部进行插入");
	LinkListPushBack(&head,'c');
	LinkListPushBack(&head,'d');
	LinkNode* pos_d = LinkListFind(head,'d');
	LinkListPrint(head,"尾插2个元素");
	LinkListInsert(&head,pos_d,'x');
	LinkListPrint(head,"d之前插入x");
	LinkListInsert(&head,NULL,'e');
	LinkListPrint(head,"NULL之前插入e");
}

void TestLinkListInsertAfter()
{
	
	TITLE;
	LinkNode* head;
	LinkListInit(&head);
	LinkListInsertAfter(&head,head,'a');
	LinkListPrint(head,"对空链表进行插入");
	
	LinkListPushBack(&head,'b');
	LinkListPushBack(&head,'c');
	LinkListPushBack(&head,'d');
	LinkListPrint(head,"尾插3个元素");
	//LinkListInsertAfter(&head,NULL,'x');
	//LinkListPrint(head,"pos为NULL时");
	LinkNode* pos_b = LinkListFind(head,'b');	
	LinkListInsertAfter(&head,pos_b,'x');
	LinkListPrint(head,"在b后插入x");
}
void TestLinkListErase()
{
	
	TITLE;
	LinkNode* head;
	LinkListInit(&head);
	LinkListPushBack(&head,'a');
	LinkListPushBack(&head,'b');
	LinkListPushBack(&head,'c');
	LinkListPushBack(&head,'d');
	LinkListPrint(head,"尾插4个元素");
	LinkNode* to_erase = LinkListFind(head,'b');
	LinkListErase(&head,to_erase);
	LinkListPrint(head,"删除元素b");
}

void TestLinkListRemove()
{
	
	TITLE;
	LinkNode* head;
	LinkListInit(&head);
	LinkListPushBack(&head,'a');
	LinkListPushBack(&head,'b');
	LinkListPushBack(&head,'c');
	LinkListPushBack(&head,'d');
	LinkListPrint(head,"尾插4个元素");
	LinkListRemove(&head,'a');
	LinkListPrint(head,"删除首元素a");
	LinkListRemove(&head,'c');
	LinkListPrint(head,"删除元素c");
}


void TestLinkListRemoveAll()
{
	
	TITLE;
	LinkNode* head;
	LinkListInit(&head);
	LinkListPushBack(&head,'b');
	LinkListPushBack(&head,'b');
	LinkListPushBack(&head,'a');
	LinkListPushBack(&head,'b');
	LinkListPushBack(&head,'c');
	LinkListPushBack(&head,'b');
	LinkListPushBack(&head,'d');
	LinkListPushBack(&head,'b');
	LinkListPrint(head,"尾插8个元素");
	LinkListRemoveAll(&head,'b');
	LinkListPrint(head,"删除元素b");
}

void TestListEmpty()
{
	TITLE;
	LinkNode* head;
	LinkListInit(&head);
	int t = LinkListEmpty(head);
	LinkListPrint(head,"判断链表是否为空,为空返回0,否则返回1");
	printf("espect is 0,actul is %d\n",t);
	LinkListPushBack(&head,'a');
	LinkListPushBack(&head,'b');
	LinkListPushBack(&head,'c');
	LinkListPushBack(&head,'d');
	LinkListPrint(head,"判断链表是否为空,为空返回0,否则返回1");
	t = LinkListEmpty(head);
	printf("espect is 1,actul is %d\n",t);
}


void TestLinkListSize()
{	
	TITLE;
	LinkNode* head;
	LinkListInit(&head);
	int t = LinkListSize(head);
	LinkListPrint(head,"打印空链表");
	printf("expect 0,actul %d\n",t);
	LinkListPushBack(&head,'a');
	LinkListPushBack(&head,'b');
	LinkListPushBack(&head,'c');
	LinkListPushBack(&head,'d');
	LinkListPrint(head,"尾插4个元素");
	t = LinkListSize(head);
	printf("expect 4,actul %d\n",t);
}


void TestLinkListReversePrint()
{	
	TITLE;
	LinkNode* head;
	LinkListInit(&head);
	printf("[逆序打印空链表]:");
	LinkListReversePrint(head);
	LinkListPushBack(&head,'a');
	LinkListPushBack(&head,'b');
	LinkListPushBack(&head,'c');
	LinkListPushBack(&head,'d');
	LinkListPrint(head,"尾插4个元素");
	printf("[逆序打印链表]:");
	LinkListReversePrint(head);
	printf("\n");
}


void TestLinkListInsertBefore()
{	
	TITLE;
	LinkNode* head;
	LinkListInit(&head);
	LinkListInsertBefore(&head,NULL,'x');
	LinkListPrint(head,"向空链表中插入x");
	LinkListPushBack(&head,'a');
	LinkListPushBack(&head,'b');
	LinkListPushBack(&head,'c');
	LinkListPushBack(&head,'d');
	LinkListPrint(head,"尾插4个元素");
	LinkNode* pos_c = LinkListFind(head,'c');
	LinkListInsertBefore(&head,pos_c,'h');
	LinkListPrint(head,"在元素c之前插入h");
}

int main()
{
	TestInit();
	TestLinkListPushBack();
	TestLinkListPopBack();
	TestLinkListPushFront();
	TestLinkListPopFront();
	TestLinkListFind();
	TestLinkListInsert();
	TestLinkListInsertAfter();
	TestLinkListErase();
	TestLinkListRemove();
	TestLinkListRemoveAll();
	TestListEmpty(); 
	TestLinkListSize();
	TestLinkListReversePrint();
	TestLinkListInsertBefore();
	return 0;
}

以下为程序运行结果:




评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值