[C语言]数据结构之双向链表

简介

本文将实现双向链表的基础接口功能
1.初始化/销毁
2.增删改查

头文件DList.h

#pragma once

//数据类型
typedef int DLDataType;

//结点类型
typedef struct DListNode{
	 DLDataType val;
	 struct DListNode *next;
	 struct DListNode *prev;
} DListNode;

//双向链表类型
typedef struct {
	 DListNode *head; //指向头结点
} DList;

//接口
//初始化/销毁
void DListInit(DList *dlist);

//清空
void DListClear(DList *dlist);

//销毁
void DListDestroy(DList *dlist);

//增删查改
//头插
void DListPushFront(DList *dlist,DLDataType val);

//尾插
void DListPushBack(DList *dlist, DLDataType val);

//查找结点
DListNode *DListFind(DList *dlist,DLDataType val);

//在pos前面插入
void DListInsert(DListNode *pos, DLDataType val);

//删除pos结点,pos不是头结点
void DListErase(DListNode *pos);

//头删
void DListPopFront(DList *dlist);
//尾删
void DListPopBack(DList *dlist);
//打印
void DListPrint(DListNode *head);

函数定义DList.c

#define _CRT_SECURE_NO_WARNINGS 1
#include "DList.h"
#include<stdlib.h>
#include<assert.h>
#include<stdio.h>

//内部结点
//创建新结点空间
DListNode *BuyNode(DLDataType val)
{
	 DListNode * node = (DListNode *)malloc(sizeof(DListNode));
	 assert(node != NULL);
	 node->val = val;
	 node->next = node->prev = NULL;
	 return node;
}

void DListInit(DList *dlist)
{
	 //创建头结点
	 //DListNode * head = (DListNode *)malloc(sizeof(DListNode));
	 DListNode * head = BuyNode(0);
	
	 //head->val = 0;
	 head->next = head;
	 head->prev = head;
	 dlist->head = head;
}

void DListClear(DList *dlist)
{
	 DListNode *cur, *next;
	 for (cur = dlist->head->next; cur != dlist->head; cur = next)
	 {
		  next = cur->next;
		  free(cur);
	 }
	
	 dlist->head->next = dlist->head;
	 dlist->head->prev = dlist->head;
}

void DListDestroy(DList *dlist)
{
	 DListClear(dlist);
	 free(dlist->head);
	 dlist->head = NULL;
}
//头插
void DListPushFront(DList *dlist, DLDataType val)
{
	 //也可以调用在pos前插入
	 DListInsert(dlist->head->next, val);

#if 0
	 //创建新结点
	 DListNode *node = BuyNode(val);
	 //调整node的前后指针指向
	 node->next = dlist->head->next;
	 node->prev = dlist->head;
	 //调整头结点的下一个结点的前指针指向
	 dlist->head->next->prev = node;
	 //调整头结点的后指针
	 dlist->head->next = node;
#endif
}

//尾插
void DListPushBack(DList *dlist, DLDataType val)
{
	 //也可以调用在pos前插入
	 DListInsert(dlist->head, val);
#if 0
	 DListNode *node = BuyNode(val);
	 node->next = dlist->head;
	 node->prev = dlist->head->prev;
	 dlist->head->prev->next = node;
	 dlist->head->prev = node;
#endif
}

//查找
DListNode *DListFind(DList *dlist, DLDataType val)
{
	 for (DListNode *cur = dlist->head->next; cur != dlist->head; cur = cur->next)
	 {
		  if (cur->val == val)
		  {
		  	 return cur;
		  }
	 }
	 return NULL;
}
//在pos结点前面插入
void DListInsert(DListNode *pos, DLDataType val)
{
	 DListNode *node = BuyNode(val);
	 node->next = pos;
	 node->prev = pos->prev;
	 pos->prev->next = node;
	 pos->prev = node;
}

void DListErase(DListNode *pos)
{
	 pos->prev->next = pos->next;
	 pos->next->prev = pos->prev;
	 free(pos);
}

//头删
void DListPopFront(DList *dlist)
{
	 assert(dlist->head->next != dlist->head);
	 //DListNode *OldFirst = dlist->head->next;
	 //dlist->head->next = dlist->head->next->next;
	 //dlist->head->next->prev = dlist->head;
	 //free(OldFirst);
	 //也可以调用删除pos结点
	 DListErase(dlist->head->next);
}

//尾删
void DListPopBack(DList *dlist)
{
	 //链表不为空
	 assert(dlist->head->next != dlist->head);
	 //DListNode *OldBack = dlist->head->prev;
	 //dlist->head->prev->prev->next = dlist->head;
	 //dlist->head->prev = dlist->head->prev->prev;
	 //free(OldBack);
	 //也可以用删除pos结点
	 DListErase(dlist->head->prev);
}

void DListPrint(DListNode *head)
{
	 for (DListNode *cur = head->next; cur != head; cur = cur->next)
	 {
	 	 printf("%d-->", cur->val);
	 }
	 printf("\n");
}

测试部分test.c

#define _CRT_SECURE_NO_WARNINGS 1
#include "DList.h"
#include<stdio.h>
#include<stdlib.h>

void test()
{
	 DList dlist;
	 DListInit(&dlist);
	
	 DListPushFront(&dlist, 3);
	 DListPushFront(&dlist, 2);
	 DListPushFront(&dlist, 1);
	 DListPrint(dlist.head);
	
	 DListPushBack(&dlist, 7);
	 DListPushBack(&dlist, 8);
	 DListPushBack(&dlist, 9);
	 DListPrint(dlist.head);
	
	 DListNode *a = DListFind(&dlist, 7);
	 DListInsert(a, 17);
	 DListPrint(dlist.head);
	
	 DListErase(a);
	 DListPrint(dlist.head);
	
	 DListPopFront(&dlist);
	 DListPrint(dlist.head);
	
	 DListPopBack(&dlist);
	 DListPrint(dlist.head);
	
	 DListClear(&dlist);
	 DListDestroy(&dlist);
}
	
int main()
{
	 test();
	 system("pause");
	 return 0;
}

猜你喜欢

转载自blog.csdn.net/Code_beeps/article/details/84930870