1. 程式人生 > >實現一個雙向連結串列的增刪改查

實現一個雙向連結串列的增刪改查

        美好的一天從中午起床開始,睡懶覺真的太舒服了,然後我們要上傳一份程式碼,實現雙向連結串列的增刪改,首先列出各個函式的功能:

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<stddef.h>
#include<stdio.h>

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<stdio.h>
#include"dlinklist.h"
#include<stdlib.h>

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<stdio.h>
#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
        以上就是實現一個雙向連結串列增刪改查功能的函式程式碼,如果你喜歡請為我點個贊,如果程式碼中有錯誤或你有更好的想法,請留言,謝謝觀看。