[Data Structure Study Notes] 2. Linked List of Linear Lists (3) (Doubly Linked List)

The linked list can be composed of eight types according to the three aspects of leading and not leading, one-way or two-way, and cyclic and acyclic. Only two of these eight types are commonly used.
The first is a unidirectional unleaded acyclic linked list, that is, a singly linked list. The singly linked list is often used in interviews because its structure is simple, but the actual operation is more complicated (because it can test the level and ability of the students~). If we often play on leetcode or Niuke.com and other problem-solving websites, we can encounter a lot of problems related to singly linked lists. If you want to review or further study the content of the singly linked list, you can refer to the article [Data Structure Study Notes] Second, Linear List - Linked List (2)
The second is the bidirectional leading circular linked list, also known as the double linked list. Although the structure of this kind of linked list is relatively complex (it is bidirectional, leading, and looping, it seems that the structure is very complicated), but the actual operation is very simple. Therefore, the linked list that is often used in our actual work or projects is this.
insert image description here

head FileDList.h

#pragma once
#include<stdio.h>
#include<stdlib.h>
#include<assert.h>
//双向带头循环链表
typedef int LTDatatype;
typedef struct DList
{
    
    
	LTDatatype data;
	struct DList* next;
	struct DList* prev;
}DList,DNode;

//创建一个节点
DNode* CreateDNode(LTDatatype x);
//链表初始化
DList* DListInit();
//销毁
void DListDestory(DList** pphead);
//打印
void DListPrint(DList* phead);
//尾插
void DListPushBack(DList* phead,LTDatatype x);
//头插
void DListPushFront(DList* phead, LTDatatype x);
//尾删
void DListPopBack(DList* phead);
//头删
void DListPopFront(DList* phead);
//查找
DNode* DListFind(DList* phead, LTDatatype x);
//在任意位置插入
void DListInsert(DNode* pos, LTDatatype x);
//在任意位置删除
void DListErase(DNode* pos);
//判空 1-为空 0-非空
int DListEmpty(DList* phead);
//求长度
int DListLength(DList* phead);

Source FileDList.c

#include"DList.h"
//创建一个节点
DNode* CreateDNode(LTDatatype x){
    
    
	DNode* node = (DNode*)malloc(sizeof(DNode));
	if (node == NULL)
	{
    
    
		printf("malloc fail!\n");
		return NULL;
	}
	node->data = x;
	node->next = NULL;
	node->prev = NULL;
	return node;
}
//链表初始化
DList* DListInit(){
    
    
	DNode* phead = CreateDNode(0);
	phead->next = phead;
	phead->prev = phead;
	return phead;
}
//销毁
void DListDestory(DList** pphead){
    
    
	assert(pphead);
	DNode* cur = (*pphead)->next;
	DNode* next = NULL;
	while (cur != *pphead)
	{
    
    
		next = cur->next;
		free(cur);
		cur = next;
	}
	*pphead = NULL;
}
//打印
void DListPrint(DList* phead){
    
    
	if (phead == NULL)
	{
    
    
		printf("The DList is empty!\n");
		return;
	}
	DNode* cur = phead->next;
	while (cur != phead)
	{
    
    
		printf("%d ", cur->data);
		cur = cur->next;
	}
	printf("\n------------------------\n");
}
//尾插
void DListPushBack(DList* phead, LTDatatype x){
    
    
	1.找到尾巴
	//DNode* tail = phead->prev;
	2.申请一个节点
	//DNode* newnode = CreateDNode(x);
	3.进行尾插操作
	//tail->next = newnode;
	//newnode->prev = tail;
	//newnode->next = phead;
	//phead->prev = newnode;

	DListInsert(phead, x);
}
//头插
void DListPushFront(DList* phead, LTDatatype x){
    
    
	//assert(phead);
	//DNode* newnode = CreateDNode(x);
	//DNode* pnext = phead->next;
	//newnode->next = pnext;
	//newnode->prev = phead;
	//pnext->prev = newnode;
	//phead->next = newnode;
	DListInsert(phead->next, x);
}
//尾删
void DListPopBack(DList* phead){
    
    
	链表为空,或链表仅有头节点
	//if (phead == NULL || phead->next == phead)
	//{
    
    
	//	printf("No element to pop!\n");
	//	return;
	//}
	//DNode* tail = phead->prev;
	//DNode* prev_tail = tail -> prev;
	尾删操作
	//prev_tail->next = phead;
	//phead->prev = prev_tail;
	//free(tail);
	//tail = NULL;

	DListErase(phead->prev);//接口复用
}
//头删
void DListPopFront(DList* phead){
    
    
	//assert(phead && (phead->next != phead));
	//DNode* first = phead->next;
	//DNode* second = first->next;
	头插操作
	//second->prev = phead;
	//phead->next = second;
	//free(first);
	//first = NULL;

	DListErase(phead->next);//接口复用
}
//查找
DNode* DListFind(DList* phead, LTDatatype x){
    
    
	assert(phead);
	DNode* cur = phead->next;
	while (cur != phead)
	{
    
    
		if (cur->data == x)
			return cur;
		cur = cur->next;
	}
	return NULL;//查找不到就返回NULL
}
//在任意位置插入--前面插入
void DListInsert(DNode* pos, LTDatatype x){
    
    
	assert(pos);
	DNode* prev = pos->prev;
	DNode* newnode = CreateDNode(x);
	newnode->next = pos;
	newnode->prev = prev;
	pos->prev = newnode;
	prev->next = newnode;
}
//在任意位置删除
void DListErase(DNode* pos){
    
    
	assert(pos && pos->next != pos);
	DNode* prev = pos->prev;
	DNode* next = pos->next;

	prev->next = next;
	next->prev = prev;
	free(pos);
	pos = NULL;
}
//判空 1-为空 0-非空
int DListEmpty(DList* phead){
    
    
	return phead->next == phead ? 1 : 0;
}
//求长度
int DListLength(DList* phead){
    
    
	int length = 0;
	DNode* cur = phead->next;
	while (cur != phead)
	{
    
    
		cur = cur->next;
		length++;
	}
}


test moduletest.c

#define _CRT_SECURE_NO_WARNINGS 1 
#include"DList.h"
void TestDList1(){
    
    
	DList* pList = DListInit();
	DListPrint(pList);

	DListPushBack(pList, 0);
	DListPushBack(pList, 1);
	DListPushBack(pList, 2);
	DListPushBack(pList, 3);
	DListPushBack(pList, 4);
	DListPushBack(pList, 5);
	DListPrint(pList);
	DListPushFront(pList, 1);
	DListPushFront(pList, 2);
	DListPushFront(pList, 3);
	DListPushFront(pList, 4);
	DListPushFront(pList, 5);
	DListPrint(pList);

	DListPopBack(pList);
	DListPopBack(pList);
	DListPopBack(pList);
	DListPopBack(pList);
	DListPopBack(pList);
	DListPrint(pList);

	int ret = DListEmpty(pList);
	printf("ret == %d\n", ret);
	int length = DListLength(pList);
	printf("length == %d\n", length);

	DListPopFront(pList);
	DListPopFront(pList);
	DListPopFront(pList);
	DListPrint(pList);

	DNode* pos = DListFind(pList, 1);
	if (pos)
	{
    
    
		DListInsert(pos, 40);
	}
	DListPrint(pList);

	DListDestory(&pList);
	DListPrint(pList);

}
int main()
{
    
    
	TestDList1();
	return 0;
}

run screenshot

insert image description here

Guess you like

Origin blog.csdn.net/QIYICat/article/details/122868302