单向链表的基本操作

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


typedef char LinkNodeType;
typedef struct LinkNode{
	struct LinkNode* next;
	LinkNodeType data;
}LinkNode;


void LinklistInit(LinkNode** node);//链表的初始化函数
void LinklistPushBack(LinkNode** phead,LinkNodeType value);//尾插函数
void LinklistPopBack(LinkNode** phead);//尾删函数
LinkNode* CreateNode(LinkNodeType value);//创建节点
void DestroyNode(LinkNode* node);//销毁节点
void LinkNodePrint(LinkNode* head,const char* msg);//打印函数
void LinklistPushFront(LinkNode** head,LinkNodeType value);//头插函数
void LinklistPopFront(LinkNode** head);//头删函数
LinkNode* LinklistFind(LinkNode* head,LinkNodeType to_find);//根据特定值寻找链表的节点
void LinklistInsertBefore(LinkNode** head,LinkNode* pos,LinkNodeType value);//在特定节点前插入一个节点,并赋值
void LinklistInsertAfter(LinkNode** head,LinkNode* pos,LinkNodeType value);//在特定节点后插入一个节点,并赋值
void LinklistErase(LinkNode** head,LinkNode* pos);//删除特定位置的节点
void LinklistRemove(LinkNode** head,LinkNodeType to_delete);//删除与特定值数据相等的第一个节点
void LinklistRemove2(LinkNode** head,LinkNodeType to_delete);//删除与特定值数据相等的第一个节点
void LinklistRemoveAll(LinkNode** head,LinkNodeType value);//删除所有与特定值数据相等的节点
int LinklistEmpyty(LinkNode* head);//判断链表是否为空的函数
size_t LinklistSize(LinkNode* head);//求链表长度的函数
LinkNode* JosephCircle(LinkNode* head,int M);//单链表实现约瑟夫环
linklist.c
#include "linklist.h"

void LinklistInit(LinkNode** node){
	if(node == NULL){
		return;
	}
	*node = NULL;
}


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


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


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


void LinklistPushBack(LinkNode** phead,LinkNodeType value){
	if(phead == NULL){
		return;
	}
	if(*phead == NULL){
		*phead=CreateNode(value);
		return;
	}
	LinkNode* cur = *phead;
	while(cur->next != NULL){
		cur = cur->next;
	}
	LinkNode* new_node=CreateNode(value);
	cur->next=new_node;
}


void LinklistPopBack(LinkNode** phead){
	if(phead == NULL){
		return;
	}
	if(*phead == NULL){
		return;
	}
	LinkNode* cur = *phead;
	if(cur->next == NULL){
		DestroyNode(cur);
		*phead = NULL;
	}
	while(cur->next != NULL){
		if(cur->next->next == NULL){
			LinkNode* to_delete=cur->next;
			cur->next=NULL;
			DestroyNode(to_delete);
}
		else{
			cur=cur->next;
		}
	}
}


void LinklistPushFront(LinkNode** head,LinkNodeType value){
	if(head == NULL){
		return;
	}
	if(*head == NULL){
		*head = CreateNode(value);
	}
	else{
	LinkNode* new_node=CreateNode(value);
	new_node->next = *head;
	*head = new_node;
	}
}


void LinklistPopFront(LinkNode** head){
	if(head == NULL){
		return;
	}
	if(*head == NULL){
		return;
	}
	LinkNode* to_delete = *head;
	*head = (*head)->next;
	DestroyNode(to_delete);
}


LinkNode* LinklistFind(LinkNode* head,LinkNodeType to_find){
	LinkNode* cur = head;
	for(;cur!=NULL;cur=cur->next){
		if(cur->data == to_find){
			printf("pos = %p\n",cur);
			return cur;
		}
	}
	return NULL;
}


void LinklistInsertBefore(LinkNode** head,LinkNode* pos,LinkNodeType value){
	if(head == NULL){
		return;
	}
	if(*head == NULL){
		*head = CreateNode(value);
		return;
	}
	if(pos == NULL){
		LinklistPushBack(head,value);
		return;
	}
	if(*head == pos){
		LinklistPushFront(head,value);
		return;
	}
	LinkNode* cur = *head;
	while(cur->next != NULL){
		if(cur->next == pos){
			LinkNode* new_node = CreateNode(value);
			new_node->next = pos;
			cur->next = new_node;
		}
		else{
			cur = cur->next;
		}
	}
	return;
}


void LinklistInsertAfter(LinkNode** head,LinkNode* pos,LinkNodeType value){
	if(head == NULL){
		return;
	}
	if(*head == NULL){
		*head = CreateNode(value);
		return;
	}
	if(pos == NULL){
		return;
	}
	LinkNode* new_node = CreateNode(value);
	new_node->next = pos->next;
	pos->next = new_node;
}


void LinklistErase(LinkNode** head,LinkNode* pos){
	if(head == NULL){
		return;
	}
	if(*head == NULL){
		return;
	}
	if(pos == NULL){
		return;
	}
	if(*head == pos){
		LinklistPopFront(head);	
		return;
	}
	LinkNode* cur = *head;
	while(cur != NULL){
		if(cur->next!=NULL){
			cur->next=pos->next;
		        DestroyNode(pos);
			return;
			}
		cur=cur->next;
}
return;
}


void LinklistRemove(LinkNode** head,LinkNodeType to_delete){
	if(head == NULL){
		return;
	}
	if(*head == NULL){
		return;
	}
	LinkNode* pos = LinklistFind(*head,to_delete);
	LinklistErase(head,pos);
}


void LinklistRemove2(LinkNode** head,LinkNodeType to_delete){
	if(head == NULL){
		return;
	}
	if(*head == NULL){
		return;
	}
	if((*head)->data == to_delete){
		LinkNode* to_delete = *head;
		*head = (*head)->next;
		DestroyNode(to_delete);
		return;
	}
	LinkNode* cur = (*head)->next;
	LinkNode* pre = *head;
	while(cur != NULL){
		if(cur->data = to_delete){
			pre->next = cur->next;
			DestroyNode(cur);
			return;
		}
		else{
			pre = pre->next;
			cur = cur->next;
		}
	}
	return;
}


void LinklistRemoveAll(LinkNode** head,LinkNodeType value){
	if(head == NULL){
		return;
	}
	if(*head == NULL){
		return;
	}
	while(1){
		LinkNode* pos = LinklistFind(*head,value);
		if(pos == NULL){
			return;
		}
		LinklistErase(head,pos);
	}
	return;
}


int LinklistEmpty(LinkNode* head){
	return head==NULL?1:0;
}


size_t LinklistSize(LinkNode* head){
	if(head == NULL){
		return 0;
	}
	size_t count = 0;
	LinkNode* cur = head;
	while(cur != NULL){
		++count;
		cur = cur->next;
	}
	printf("count = %d\n",count);
	return count;
}


LinkNode* JosephCircle(LinkNode* head,int M){
	if(head == NULL){
		return;
	}
	LinkNode* cur = head;
	while(cur->next != cur){
		int i = 1;
		for(;i<M;++i){
			cur = cur->next;
		}
		printf("%c\n",cur->data);
		cur->data = cur->next->data;
		LinkNode* to_delete = cur->next;
		cur->next = to_delete->next;
		DestroyNode(to_delete);
	}
	return cur;
}
test.c
#include"linklist.h"
#define PRINT_HEAD printf("\n==========%s==========\n",__FUNCTION__)


void TestInit(){
	PRINT_HEAD;
	LinkNode* head;
	LinklistInit(&head);
}


void TestLinklistPushBack(){
	PRINT_HEAD;
	LinkNode* head;
	LinklistInit(&head);

	LinklistPushBack(&head,'a');
	LinklistPushBack(&head,'b');
	LinklistPushBack(&head,'c');
	LinklistPushBack(&head,'d');
	LinkNodePrint(head,"insert four elements to the linklist");
}


void TestLinklistPopBack(){
	PRINT_HEAD;
	LinkNode* head;
	LinklistInit(&head);

	LinklistPushBack(&head,'a');
	LinklistPushBack(&head,'b');
	LinklistPushBack(&head,'c');
	LinklistPushBack(&head,'d');
	LinklistPopBack(&head);
	LinklistPopBack(&head);
	LinkNodePrint(head,"delete two elements from the linklist");

}


void TestLinklistPushFront(){
	PRINT_HEAD;
	LinkNode* head;
	LinklistInit(&head);

	LinklistPushFront(&head,'a');
	LinklistPushFront(&head,'b');
	LinklistPushFront(&head,'c');
	LinklistPushFront(&head,'d');
	LinkNodePrint(head,"insert four elements from the linklist");
}


void TestLinklistPopFront(){
	PRINT_HEAD;
	LinkNode* head;
	LinklistInit(&head);

	LinklistPushBack(&head,'a');
	LinklistPushBack(&head,'b');
	LinklistPushBack(&head,'c');
	LinklistPushBack(&head,'d');
	LinklistPopFront(&head);
	LinklistPopFront(&head);
	LinkNodePrint(head,"delete two elements from the linklist");
}


void TestLinklistFind(){
	PRINT_HEAD;
	LinkNode* head;
	LinklistInit(&head);

	LinklistPushFront(&head,'a');
	LinklistPushFront(&head,'b');
	LinklistPushFront(&head,'c');
	LinklistPushFront(&head,'d');
	LinklistFind(head,'c');
}


void TestLinklistInsertBefore(){
	PRINT_HEAD;
	LinkNode* head;
	LinklistInit(&head);

	LinklistPushBack(&head,'a');
	LinklistPushBack(&head,'b');
	LinklistPushBack(&head,'c');
	LinklistPushBack(&head,'d');
	LinklistInsertBefore(&head,head,'x');
	LinkNodePrint(head,"insert an element before the head");
}


void TestLinklistInsertAfter(){
	PRINT_HEAD;
	LinkNode* head;
	LinklistInit(&head);

	LinklistPushBack(&head,'a');
	LinklistPushBack(&head,'b');
	LinklistPushBack(&head,'c');
	LinklistPushBack(&head,'d');
	LinklistInsertAfter(&head,head,'x');
	LinkNodePrint(head,"insert an element after the head");
}


void TestLinklistErase(){
	PRINT_HEAD;
	LinkNode* head;
	LinklistInit(&head);

	LinklistPushBack(&head,'a');
	LinklistPushBack(&head,'b');
	LinklistPushBack(&head,'c');
	LinklistPushBack(&head,'d');
	LinkNode* pb = LinklistFind(head,'b');
	LinklistErase(&head,pb);
	LinkNodePrint(head,"erase an element from the specific position");
}


void TestLinklistRemove(){
	PRINT_HEAD;
	LinkNode* head;
	LinklistInit(&head);

	LinklistPushBack(&head,'a');
	LinklistPushBack(&head,'b');
	LinklistPushBack(&head,'c');
	LinklistPushBack(&head,'d');
	LinklistRemove(&head,'b');
	LinkNodePrint(head,"remove an element from the specific value");
}


void TestLinklistRemove2(){
	PRINT_HEAD;
	LinkNode* head;
	LinklistInit(&head);

	LinklistPushBack(&head,'a');
	LinklistPushBack(&head,'b');
	LinklistPushBack(&head,'c');
	LinklistPushBack(&head,'d');
	LinklistRemove(&head,'b');
	LinkNodePrint(head,"remove an element from the specific value");
}


void TestLinklistRemoveAll(){
	PRINT_HEAD;
	LinkNode* head;
	LinklistInit(&head);

	LinklistPushBack(&head,'a');
	LinklistPushBack(&head,'b');
	LinklistPushBack(&head,'b');
	LinklistPushBack(&head,'a');
	LinklistPushBack(&head,'c');
	LinklistPushBack(&head,'d');
	LinklistRemoveAll(&head,'b');
	LinkNodePrint(head,"remove  elements from the specific value");
}


void TestLinklistEmpty(){
	PRINT_HEAD;
	LinkNode* head;
	LinklistInit(&head);

	int ret = LinklistEmpty(head);
	printf("expect 1, actual %d\n",ret);
	LinklistPushBack(&head,'a');
	LinklistPushBack(&head,'b');
	LinklistPushBack(&head,'c');
	LinklistPushBack(&head,'d');
	ret = LinklistEmpty(head);
	printf("expect 0, actual %d\n",ret);
}


void TestLinklistSize(){
	PRINT_HEAD;
	LinkNode* head;
	LinklistInit(&head);

	LinklistPushBack(&head,'a');
	LinklistPushBack(&head,'b');
	LinklistPushBack(&head,'c');
	LinklistPushBack(&head,'d');
	size_t ret = LinklistSize(head);
	printf("expect 4, actual %d\n",ret);
}


void TestJosephCircle(){
		PRINT_HEAD;
		LinkNode* a = CreateNode('a');
		LinkNode* b = CreateNode('b');
		LinkNode* c = CreateNode('c');
		LinkNode* d = CreateNode('d');
		LinkNode* e = CreateNode('e');
		LinkNode* f = CreateNode('f');
		LinkNode* g = CreateNode('g');
		a->next = b;
		b->next = c;
		c->next = d;
		d->next = e;
		e->next = f;
		f->next = g;
		g->next = a;
		LinkNode* survive = JosephCircle(a,5);
		printf("survive is %c\n",survive->data);
}



int main(){
	TestInit();
	TestLinklistPushBack();
	TestLinklistPopBack();
	TestLinklistPushFront();
	TestLinklistPopFront();
	TestLinklistFind();
	TestLinklistInsertBefore();
	TestLinklistInsertAfter();
	TestLinklistErase();
	TestLinklistRemove();
	TestLinklistRemove2();
	TestLinklistRemoveAll();
	TestLinklistEmpty();
	TestLinklistSize();
	TestJosephCircle();
}



  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值