带头节点双向链表的基本操作

带头节点双向链表有两个指针分别指向前一个节点(prev)和后一个节点(next);用图可以表示为:

带头节点双向链表的基本操作_第1张图片

DLinkList.h

#define _CRT_SECURE_NO_WARNINGS 1
#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 DLinkListPopBack(DLinkNode* head);

 void DLinkListPushFront(DLinkNode* head, DLinkType value);

 void DLinkListPopFront(DLinkNode* head);

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

 /**
   *  * @brief 往指定位置之前插入一个元素
   */
  void DLinkListInsert(DLinkNode* pos, DLinkType value);
  
   /**
    *  * @brief 往指定位置之后插入一个元素
    *  */
void DLinkListInsertAfter(DLinkNode* pos, DLinkType value);
void DLinkListErase(DLinkNode* head, DLinkNode* pos);


void DLinkListRemove(DLinkNode* head,DLinkType to_find);


void DLinkListRemoveAll(DLinkNode* head, DLinkType to_find);


size_t DLinkListSize(DLinkNode* head);


int DLinkListEmpty(DLinkNode* head);

DLinkList.c

#define _CRT_SECURE_NO_WARNINGS 1
#include "DLinkList.h"                                                                                                           
#include
void DLinkListFree(DLinkNode* to_delete){
	/*
	释放空间
	*/
	free(to_delete);
}
DLinkNode* CreatNode(DLinkType value){
	DLinkNode* ptr = (DLinkNode*)malloc(sizeof(DLinkNode));
	if (ptr == NULL){
		return NULL;
	}
	ptr->data = value;//NULL<--data-->NULL
	ptr->next = NULL;
	ptr->prev = NULL;
	return ptr;
}
void DLinkListInit(DLinkNode** head){

	DLinkNode* new_node = CreatNode(0);
	*head =new_node;
	(*head)->next = new_node;
	(*head)->prev = new_node; 
	return;
}

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

	if (head == NULL){
		//非法输入
		 return NULL;		
	}
	 DLinkNode* new_node = CreatNode(value);
	 if (head->next == head){
		 //head---new_node
		 head->next = new_node;
		 head->prev = new_node;
		 new_node->next = head;
		 new_node->prev = head;
		 return head;
	 }
		 DLinkNode* pre = head->prev;
		 pre->next = new_node;
		 new_node->prev = pre;
		 new_node->next = head;
		 head->prev = new_node;
		 return head;
}
void DLinkListPopBack(DLinkNode* head)
{
	if (head == NULL||head->next==head){
		return;
	}
	DLinkNode* to_delete = head->prev;
	head->prev = to_delete->prev;
	to_delete->prev->next = head;
	DLinkListFree(to_delete);
	return;
}
void DLinkListPushFront(DLinkNode* head, DLinkType value)
{
	if (head == NULL){
		return;
	}
	DLinkNode* new_node = CreatNode(value);
	if (head->next == head){
		head->next = new_node;
		head->prev = new_node;
		new_node->next = head;
		new_node->prev = head;
		return;
	}
	DLinkNode* next = head->next;
	//new_node--next
	new_node->next = next;
	next->prev = new_node;
	new_node->prev=head;
	head->next = new_node;
	//new_node---head
}
void DLinkListPopFront(DLinkNode* head)
{
	if (head == NULL||head->next==head){
		//非法输入
		return;
	}
	DLinkNode* to_delete = head->next;
	head->next = to_delete->next;
	to_delete->next->prev = head;
	DLinkListFree(to_delete);
	return;
}
DLinkNode* DLinkListFind(DLinkNode* head, DLinkType to_find)
{
	if (head == NULL){
		//非法输入
		return NULL;
	}
	DLinkNode* cur = head->next;
	for (; cur != head; cur = cur->next){
		if (cur->data == to_find){
			return cur;
		}
	}
	return NULL;
}
void DLinkListInsert(DLinkNode* pos, DLinkType value)
{
	DLinkNode* new_node = CreatNode(value);
	DLinkNode* pre = pos->prev;

	new_node->next = pos;
	pos->prev = new_node;
	pre->next = new_node;
	new_node->prev = pre;
	return;
}
void DLinkListInsertAfter(DLinkNode* pos, DLinkType value)
{
	DLinkNode* new_node = CreatNode(value);
	DLinkNode* nex = pos->next;
	new_node->next = nex;
	nex->prev = new_node;
	pos->next = new_node;
	new_node->prev = pos;
	return;
}
void DLinkListErase(DLinkNode* head, DLinkNode* pos)
{
	if (head == NULL||head==pos){
		//非法输入
		return;
	}
	DLinkNode* to_delete = pos;
	DLinkNode* pre = to_delete->prev;
	DLinkNode* nex = to_delete->next;
	pre->next = nex;
	nex->prev = pre;
	DLinkListFree(to_delete);
	return;
}
void DLinkListRemove(DLinkNode* head, DLinkType to_find)
{
	if (head == NULL){
		//非法输入
		return;
	}
	DLinkNode* pos = DLinkListFind(head, to_find);
	if (pos == NULL){
		//没找到则返回
		return;
	}
	DLinkListErase(head, pos);
	return;
}
void DLinkListRemoveAll(DLinkNode* head, DLinkType to_find)
{
	if (head == NULL){
		//非法输入
		return;
	}
	while (1){
		DLinkNode* pos = DLinkListFind(head, to_find);
		if (pos == NULL){
			//没找到则返回
			break;
		}
		DLinkListErase(head, pos);
	}
}
size_t DLinkListSize(DLinkNode* head)
{
	if (head == NULL || head->next == head){
		return 0;
	}
	size_t count = 0;
	DLinkNode* cur = head->next;
	for (; cur != head; cur = cur->next){
		count++;
	}
	return count;
}
int DLinkListEmpty(DLinkNode* head)
{
	if (head == NULL){
		return -1;
	}
	if (head->next == head){
		return 0;
	}
	return 1;
}
//测试代码//
#define PrintHeader printf("\n------------------%s-----------\n",__FUNCTION__)
void PrintChar(DLinkNode* head, DLinkType *msg)
{
   if (head == NULL) {
	//非法输入
    return;
   }
  printf("[%s]\n", msg);
  DLinkNode* cur = head->next;
  for (; cur != head; cur = cur->next){
	  printf("[%c]  ", cur->data);
  }
  printf("\n");
  for (cur=head->prev; cur != head; cur = cur->prev){
	  printf("[%c]  ", cur->data);
  }
  printf("\n");
   return;
  }
void TestInit(){
	 PrintHeader;
	 DLinkNode* head;
	 DLinkListInit(&head);
	 printf("expect NULL,actuall %p\n", head);
	 printf("expect NULL,actuall %d\n", (int)head->data);

}
void TestPushBack(){
	PrintHeader;
	DLinkNode* head;
	DLinkListInit(&head);
	DLinkListPushBack(head, 'a');
	DLinkListPushBack(head, 'b');
	DLinkListPushBack(head, 'c');
	DLinkListPushBack(head, 'd');
	PrintChar(head, "尾插四个元素");
		
}
void TestPopBack(){
	PrintHeader;
	DLinkNode* head;
	DLinkListInit(&head);
	DLinkListPushBack(head, 'a');
	DLinkListPushBack(head, 'b');
	DLinkListPushBack(head, 'c');
	DLinkListPushBack(head, 'd');
	DLinkListPopBack(head);
	PrintChar(head, "尾删一个元素");
}
void TestPushFront(){
	PrintHeader;
	DLinkNode* head;
	DLinkListInit(&head);
	DLinkListPushFront(head, 'a');
	DLinkListPushFront(head, 'b');
	DLinkListPushFront(head, 'c');
	DLinkListPushFront(head, 'd');
	PrintChar(head, "头插四个元素"); 
}
void TestPopFront(){
	PrintHeader;
	DLinkNode* head;
	DLinkListInit(&head);
	DLinkListInit(&head);
	DLinkListPushBack(head, 'a');
	DLinkListPushBack(head, 'b');
	DLinkListPushBack(head, 'c');
	DLinkListPushBack(head, 'd');
	PrintChar(head, "尾插四个元素");
	DLinkListPopFront(head);
	DLinkListPopFront(head);
	PrintChar(head, "头删两个元素");
}
void TestDLinkListFind(){
	PrintHeader;
	DLinkNode* head;
	DLinkListInit(&head);
	DLinkListInit(&head);
	DLinkListPushBack(head, 'a');
	DLinkListPushBack(head, 'b');
	DLinkListPushBack(head, 'c');
	DLinkListPushBack(head, 'd');
	PrintChar(head, "尾插四个元素");
	DLinkNode* ret = DLinkListFind(head, 'c');
	printf("expect c,actual %c\n", ret->data);
}
void TestInsert(){
	PrintHeader;
	DLinkNode* head;
	DLinkListInit(&head);
	DLinkListInit(&head);
	DLinkListPushBack(head, 'a');
	DLinkListPushBack(head, 'b');
	DLinkListPushBack(head, 'c');
	DLinkListPushBack(head, 'd');
	PrintChar(head, "尾插四个元素");
	DLinkListInsert(head->next->next->next, 'X');
	PrintChar(head, "在c前插入字符X");
}
void TestInsertAfter(){
	PrintHeader;
	DLinkNode* head;
	DLinkListInit(&head);
	DLinkListInit(&head);
	DLinkListPushBack(head, 'a');
	DLinkListPushBack(head, 'b');
	DLinkListPushBack(head, 'c');
	DLinkListPushBack(head, 'd');
	PrintChar(head, "尾插四个元素");
	DLinkListInsertAfter(head->next->next, 'X');
	PrintChar(head,"在b的后面插入");
}
void TestErase(){
	PrintHeader;
	DLinkNode* head;
	DLinkListInit(&head);
	DLinkListPushBack(head, 'a');
	DLinkListPushBack(head, 'b');
	DLinkListPushBack(head, 'c');
	DLinkListPushBack(head, 'd');
	PrintChar(head, "尾插四个元素");
	DLinkListErase(head, head->next->next);
	PrintChar(head, "删除b");
}
void TestRemove(){
	PrintHeader;
	DLinkNode* head;
	DLinkListInit(&head);
	DLinkListPushBack(head, 'a');
	DLinkListPushBack(head, 'b');
	DLinkListPushBack(head, 'c');
	DLinkListPushBack(head, 'd');
	PrintChar(head, "尾插四个元素");
	DLinkListRemove(head, 'c');
	PrintChar(head, "删除c");
}
void TestRemoveAll(){
	PrintHeader;
	DLinkNode* head;
	DLinkListInit(&head);
	DLinkListPushBack(head, 'a');
	DLinkListPushBack(head, 'c');
	DLinkListPushBack(head, 'b');
	DLinkListPushBack(head, 'c');
	DLinkListPushBack(head, 'd');
	PrintChar(head, "尾插四个元素");
	DLinkListRemoveAll(head, 'c');
	PrintChar(head, "删除所有的c");
}
void TestDLinkListSize(){
	PrintHeader;
	DLinkNode* head;
	DLinkListInit(&head);
	DLinkListPushBack(head, 'a');
	DLinkListPushBack(head, 'c');
	DLinkListPushBack(head, 'b');
	DLinkListPushBack(head, 'c');
	DLinkListPushBack(head, 'd');
	size_t ret = DLinkListSize(head);
	printf("expect 5,actual %u\n", ret);
}
void TestDLinkListEmpty(){
	PrintHeader;
	DLinkNode* head;
	DLinkListInit(&head);
	int ret1 = DLinkListEmpty(head);
	printf("expect 0,actual %d\n", ret1);
	DLinkListInit(&head);
	DLinkListPushBack(head, 'a');
	DLinkListPushBack(head, 'c');
	DLinkListPushBack(head, 'b');
	DLinkListPushBack(head, 'c');
	PrintChar(head, "尾插四个元素");
	int ret2 = DLinkListEmpty(head);
	printf("expect 1,actual %d\n", ret2);


}
 ///main函数调用
 int main()
 {
         TestInit();//初始化
         TestPushBack();//尾插
	 TestPopBack();//尾删
	 TestPushFront();//前插
	 TestPopFront();//前删
	 TestDLinkListFind();//在链表中找value
	 TestInsert();//指定位置后插入
	 TestInsertAfter();//指定位置前插
         TestErase();//删除指定位置节点
	 TestRemove();//删除一个指定字符
	 TestRemoveAll();//删除所有指定字符
	 TestDLinkListSize();//求链表的节点数
	 TestDLinkListEmpty();//判断链表是否为空
	 system("pause");
         return 0;
	 
 }

带头节点双向链表的基本操作_第2张图片

同理,以上的基本操作都需要修改相关节点的两个指针的指向

你可能感兴趣的:(带头节点双向链表的基本操作)