实现一个双向链表的增删改查

        美好的一天从中午起床开始,睡懒觉真的太舒服了,然后我们要上传一份代码,实现双向链表的增删改,首先列出各个函数的功能:

        

void DLinkListInit(DLinkNode** head);  双向链表的初始化
DLinkNode* DLinkListPushBack(DLinkNode* head, DLinkType value);  尾插一个元素
void DLinListPopBack(DLinkNode* head);  尾删一个元素
void DLinkListPushFront(DLinkNode* head, DLinkType value);  头插一个元素
void DLinkListPopFront(DLinkNode* head);  头删一个元素
DLinkNode* DLinkListFind(DLinkNode* head, DLinkType to_find);  根据指定元素值找到并返回节点下标
void DLinkListInsert(DLinkNode* pos, DLinkType value);  往指定位置之前插入一个元素
void DLinkListInsertAfter(DLinkNode* pos, DLinkType value); 往指定位置之后插入一个元素

更新:

        更新了双向链表的指定位置删除节点,求链表的长度和是否为空等功能。首先通过列表展示各函数功能

void DLinkListErase(DLinkNode* head,DLinkNode* pos); 删除指定位置的节点
void DLinkListRemove(DLinkNode* head,DLinkType value); 去除双向链表中第一个值为value的节点
void DLinkListRemoveAll(DLinkNode* head,DLinkType value); 去除双向链表中所有值为value的节点
size_t DLinkListSize(DLinkNode* head); 求出双向链表的长度
int DLinkListEmpty(DLinkNode* head); 判断双向链表是否为空链表,是返回0,否返回1

dlinklist.h

#include
#include

typedef char DLinkType;
typedef struct DLinkNode{
	DLinkType data;
	struct DLinkNode* next;
	struct DLinkNode* prev;

}DLinkNode;

void DLinkListInit(DLinkNode** head);

DLinkNode* DLinkListPushBack(DLinkNode* head,DLinkType value);

void DLinkListPushFront(DLinkNode* head,DLinkType value);

void DLinkListPopBack(DLinkNode* head);

void DLinkListPopFront(DLinkNode* head);

DLinkNode* DLinkListFind(DLinkNode* head,DLinkType to_find);

void DLinkListInsert(DLinkNode* head,DLinkNode* pos,DLinkType value);

void DLinkListInsertAfter(DLinkNode* head,DLinkNode* pos,DLinkType value);

更新:

void DLinkListErase(DLinkNode* head,DLinkNode* pos);

void DLinkListRemove(DLinkNode* head,DLinkType value);

void DLinkListRemoveAll(DLinkNode* head,DLinkType value);

size_t DLinkListSize(DLinkNode* head);

int DLinkListEmpty(DLinkNode* head);

dlinklist.c

#include
#include"dlinklist.h"
#include

DLinkNode* CreateDLinkNode(DLinkType value){
	DLinkNode* new_node = (DLinkNode*)malloc(sizeof(DLinkType));
	new_node->data = value;
	new_node->prev = new_node;
	new_node->next = new_node;
	return new_node;
}

void DLinkListInit(DLinkNode** head){
	if(head == NULL){
		return;//feifashuru
	}
	*head == CreateDLinkNode(0);
}

void DestoryNode(DLinkNode* to_delete){
	free(to_delete);
}

DLinkNode* DLinkListPushBack(DLinkNode* head,DLinkType value){
	if(head == NULL){
		return NULL;
	}
	DLinkNode* tail = head->prev;
	DLinkNode* new_node = CreateDLinkNode(value);
	head->prev = new_node;
	new_node->next = head;
	tail->next = new_node;
	new_node->prev = tail;
	return head;
}



void DLinkListPushFront(DLinkNode* head,DLinkType value){
	if(head == NULL){
		return;
	}
	DLinkNode* new_node = CreateDLinkNode(value);
	DLinkNode* cur = head->next;
	cur->prev = new_node;
	new_node->next = cur;
	head->next = new_node;
	new_node->prev = head;
	return;
}

void DLinkListPopBack(DLinkNode* head){
	if(head == NULL){
		return;
	}
	if(head->next == head && head->prev == head){
		return;
	}
	DLinkNode* to_delete = head->prev;
	DLinkNode* pre = to_delete->prev;
	pre->next = head;
	head->prev = pre;
	DestoryNode(to_delete);
	return;
}

void DLinkListPopFront(DLinkNode* head){
	if(head == NULL){
		return;
	}
	if(head->next == head && head->prev == head){
		return;
	}
	DLinkNode* to_delete = head->next;
	DLinkNode* to_delete_next = to_delete->next;
	head->next = to_delete_next;
	to_delete_next->prev = head;
	DestoryNode(to_delete);
	return;
}

DLinkNode* DLinkListFind(DLinkNode* head,DLinkType to_find){
	 if(head == NULL){
		 return NULL;
	 }
	 DLinkNode* cur = head->next;
	 while(cur != head){
		if(cur->data == to_find){
			break;
		}
		cur = cur->next;
	 }
	 if(cur == head){
		 return NULL;
	 }
	 return cur;
}

void DLinkListInsert(DLinkNode* head,DLinkNode* pos,DLinkType value){//pos之前插入
	if(head == NULL || pos == NULL){
		return;
	}
	DLinkNode* new_node = CreateDLinkNode(value);
	DLinkNode* pre = pos->prev;
	new_node->prev = pre;
	pre->next = new_node;

	new_node->next = pos;
	pos->prev = new_node;
	return;
}

void DLinkListInsertAfter(DLinkNode* head,DLinkNode* pos,DLinkType value){
	if(head == NULL || pos == NULL){
		return;
	}
	DLinkNode* cur = pos->next;
	DLinkNode* new_node = CreateDLinkNode(value);
	new_node->next = cur;
	new_node->prev = pos;
	pos->next = new_node;
	cur->prev = new_node;
	return;
}

更新:

void DLinkListErase(DLinkNode* head,DLinkNode* pos){
	if(head == NULL){
		return;
	}
	DLinkNode* cur = pos->next;
	DLinkNode* pre = pos->prev;
	pre->next = cur;
	cur->prev = pre;
	DestoryNode(pos);
	return;
}

void DLinkListRemove(DLinkNode* head,DLinkType value){
	if(head == NULL){
		return;
	}
	DLinkNode* to_remove = DLinkListFind(head,value);
	DLinkNode* to_remove_prev = to_remove->prev;
	DLinkNode* to_remove_next = to_remove->next;
	to_remove_prev->next = to_remove_next;
	to_remove_next->prev = to_remove_prev;
	DestoryNode(to_remove);
	return;
}

void DLinkListRemoveAll(DLinkNode* head,DLinkType value){
	if(head == NULL)	{
		return;
	}
	DLinkNode* to_remove = head->next;
	while(to_remove != head){
		if(to_remove->data == value){
			DLinkListRemove(head,value);
		}
		to_remove = to_remove->next;
	}
	return;	
}

size_t DLinkListSize(DLinkNode* head){
	if(head == NULL){
		return;
	}
	DLinkNode* start = head->next;
	size_t len = 1;
	while(start != head){
		start = start->next;
		++len;
	}
	return len;
}

int DLinkListEmpty(DLinkNode* head){
	if(head == NULL){
		return;
	}
	if(head->next == head && head->prev){
		return 0;
	}
	return 1;
} 




///
//测试函数
///
#if 1
#include
#define TEST_HEADER printf("\n=========%s=========\n",__FUNCTION__);
void DLinkListPrintChar(DLinkNode* head,const char* msg){
	printf("[%s]\n",msg);
	DLinkNode* cur = head->next;
	for(;cur != head;cur = cur->next){
		printf("[%c]%p",cur->data,cur);
	}
	for(;cur = head->prev;cur != head){
		printf("[]%c]%p",cur->data,cur);
	}
	printf("\n");
}

测试函数更新:

void TestEmpty(){
	TEST_HEADER;
	DLinkNode* head;
	DLinkListInit(&head);
	DLinkListPushBack(head,'a');
	int ret = DLinkListEmpty(head);
	printf("有内容,excepted 1,actual %d\n",ret);
	DLinkListPopBack(head);
	ret = DLinkListEmpty(head);
	printf("无内容,excepted 0 ,actual %d\n",ret);
}

void TestSize(){
	TEST_HEADER;
	DLinkNode* head;
	DLinkListInit(&head);
	DLinkListPushBack(head,'a');
	DLinkListPushBack(head,'b');
	DLinkListPushBack(head,'c');
	int len = DLinkListSize(head);
	printf("链表的长度为%d\n",len);
	DLinkListPrintChar(head,"输出链表的长度");
}


void TestRemoveAll(){
	TEST_HEADER;
	DLinkNode* head;
	DLinkListInit(&head);
	DLinkListPushBack(head,'a');
	DLinkListPushBack(head,'b');
	DLinkListPushBack(head,'c');
	DLinkListPushBack(head,'b');
	DLinkListRemoveAll(head,'b');
	DLinkListPrintChar(head,"删除此链表中所有的b");
}


void TestRemove(){
	TEST_HEADER;
	DLinkNode* head;
	DLinkListInit(&head);
	DLinkListPushBack(head,'a');
	DLinkListPushBack(head,'b');
	DLinkListPushBack(head,'c');
	DLinkListPushBack(head,'b');
	DLinkListRemove(head,'b');
	DLinkListPrintChar(head,"删除链表中第一个b");
}

void TestErase(){
	TEST_HEADER;
	DLinkNode* head;
	DLinkListInit(&head);
	DLinkListPushBack(head,'a');
	DLinkListPushBack(head,'b');
	DLinkListPushBack(head,'c');
	pos = DLinkListFind(head,'b');
	DLinkListErase(head,pos);
	DLinkListPrintChar(head,"删除pos位置的元素");
}



void TestInsertAfter(){
	TEST_HEADER;
	DLinkNode* head;
	DLinkListInit(&head);
	DLinkListPushBack(head,'a');
	DLinkListPushBack(head,'b');
	DLinkListPushBack(head,'c');
	DLinkNode* pos = DLinkListFind(head,'b');
	DLinkListInsertAfter(head,pos,'y');
	DLinkListPrintChar(head,"在 b 之后插入一个 y");//预期结果:a b y c
}

void TestInsert(){
	TEST_HEADER;
	DLinkNode* head;
	DLinkListInit(&head);
	DLinkListPushBack(head,'a');
	DLinkListPushBack(head,'b');
	DLinkListPushBack(head,'c');
	DLinkNode* pos = DLinkListFind(head,'b');
	DLinkListInsert(head,pos,'x');
	DLinkListPrintChar(head,"在 b 之前插入一个 x");//预期结果:a x b c
}

void TestFind(){
	TEST_HEADER;
	DLinkNode* head;
	DLinkListInit(&head);
	DLinkListPushBack(head,'a');
	DLinkListPushBack(head,'b');
	DLinkListPushBack(head,'c');
	DLinkListFind(head,'c');
	DLinkListPrintChar(head,"查询元素 c");}

void TestPopFront(){
	TEST_HEADER;
	DLinkNode* head;
	DLinkListInit(&head);
	DLinkListPushBack(head,'a');
	DLinkListPushBack(head,'b');
	DLinkListPushBack(head,'c');
	DLinkListPopFront(head);
	DLinkListPrintChar(head,"头删一个元素");
}

void TestPopBack(){
	TEST_HEADER;
	DLinkNode* head;
	DLinkListInit(&head);
	DLinkListPushBack(head,'a');
	DLinkListPushBack(head,'b');
	DLinkListPopBack(head);
	DLinkListPrintChar(head,"尾删一个元素");
}

void TestInit(){
	TEST_HEADER;
	DLinkNode* head;
	DLinkListInit(&head);
	printf("head excepted not NULL,actual %p\n",head);
	printf("data excepted 0,actual %d\n",head->data);
}

void TestPushBack(){
	TEST_HEADER;
	DLinkNode* head;
	DLinkListInit(&head);
	DLinkListPushBack(head,'a');
	DLinkListPushBack(head,'b');
	DLinkListPushBack(head,'c');
	DLinkListPushBack(head,'d');
	DLinkListPrintChar(head,"尾插四个元素");
}


void TestPushFront(){
	TEST_HEADER;
	DLinkNode* head;
	DLinkListInit(&head);
	DLinkListPushFront(head,'a');
	DLinkListPrintChar(head,"头插一个元素");
}

int main(){
	TestInit();
	TestPushBack();
	TestPushFront();
	TestPopBack();
	TestPopFront();
	TestFind();
	TestInsert();
	TestInsertAfter();
	TestErase();
	TestRemove();
	TestRemoveAll();
	TestSize();
	TestEmpty();
	return 0;
}

#endif
        以上就是实现一个双向链表增删改查功能的函数代码,如果你喜欢请为我点个赞,如果代码中有错误或你有更好的想法,请留言,谢谢观看。

你可能感兴趣的:(数据结构-链表)