链表(三)-----双向链表

前两篇博客中介绍的链式储存结构中只有一个指示直接后继的指针域。因此,从单链表中的某个结点出发,之能向后遍历每个结点,所寻找这个结点的直接前驱只能向用头结点出。
而若在每个结点的指针域中再加入一个指向当前结点直接前驱的指针,就可以克服以上问题。

在这里插入图片描述

DList.h

#pragma once
//双向链表,带头节点,头的前驱为NULL,尾的后继为NULL

typedef struct DNode
{
	int data;
	struct DNode *next;//后继指针
	struct DNode *prio;//前驱指针
}DNode,*DList;

//初始化
void InitList(DList plist);

//头插法
bool Insert_head(DList plist,int val);

//尾插
bool Insert_tail(DList plist,int val);

//查找
DNode *Search(DList plist,int key);

//删除
bool Delete(DList plist,int key);

bool IsEmpty(DList plist);

//获取长度,数据个数
int GetLength(DList plist);

void Show(DList plist);

//获得key的前驱
DNode *GetPrio(DList plist,int key);

//获取key后继
DNode *GetNext(DList plist,int key);

//清空数据
void Clear(DList plist);

//销毁
void Destroy(DList plist);

DList.cpp

#include <stdio.h>
#include <stdlib.h>
#include <assert.h>
#include "dlist.h"
//双向链表,带头节点,头的前驱为NULL,尾的后继为NULL
//初始化
void InitList(DList plist)
{
	assert(plist != NULL);
	if(plist == NULL)
	{
		return ;
	}

	plist->next = NULL;
	plist->prio = NULL;
}

//头插法
bool Insert_head(DList plist,int val)
{
	DNode *p = (DNode *)malloc(sizeof(DNode));
	p->data = val;

	p->next = plist->next;//1先绑绳子
	plist->next = p;//2
	p->prio = plist;
	if(p->next != NULL)
	{
		p->next->prio = p;
	}

	return true;
}

//尾插
bool Insert_tail(DList plist,int val)
{
	DNode *p = (DNode *)malloc(sizeof(DNode));
	p->data = val;

	DNode *q;
	for(q=plist;q->next!=NULL;q=q->next);

	p->next = q->next;
	p->prio = q;
	q->next = p;

	return true;
}

//查找
DNode *Search(DList plist,int key)
{
	for(DNode *p=plist->next;p!=NULL;p=p->next)
	{
		if(p->data == key)
		{
			return p;
		}
	}
	return NULL;
}

//删除
bool Delete(DList plist,int key)
{
	DNode *p = Search(plist,key);
	if(p == NULL)
	{
		return false;
	}

	//将p从链表中剔除
	p->prio->next = p->next;
	if(p->next != NULL)
	{
		p->next->prio = p->prio;
	}
	free(p);
	return true;
}

bool IsEmpty(DList plist)
{
    return plist->next = NULL;
}

//获取长度,数据个数
int GetLength(DList plist)
{
    int count=0;
    for (DNode *p = plist; p->next != pilst; p = p->next)
    {
        count++;
    }
    return count;
}

void Show(DList plist)
{
	for(DNode *p=plist->next;p!=NULL;p=p->next)
	{
		printf("%d ",p->data);
	}
	printf("\n");
}

//获得key的前驱
DNode *GetPrio(DList plist, int key)
{
    DNode *q = Search(plist, key);
    return q->prio;

}

//获取key后继
DNode *GetNext(DList plist, int key)
{
    DNode *q = Search(plist, key);
    return q->next;
}

//清空数据
void Clear(DList plist)
{
    Destroy(plist);
}

//销毁
void Destroy(DList plist)
{
    DNode *p;
    while (plist->next != plist)
    {
        p = plist->next;
        plist->next = p->next;
        free(p);
    }
}

下一篇静态链表实现与分析