鏈表(三)-----雙向鏈表

前兩篇博客中介紹的鏈式儲存結構中只有一個指示直接後繼的指針域。因此,從單鏈表中的某個結點出發,之能向後遍歷每個結點,所尋找這個結點的直接前驅只能向用頭結點出。
而若在每個結點的指針域中再加入一個指向當前結點直接前驅的指針,就可以克服以上問題。

在這裏插入圖片描述

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);
    }
}

下一篇靜態鏈表實現與分析