数据结构--双向链表

双向链表:

双向链表也叫双链表,是链表的一种,它的每个数据结点中都有两个指针,分别指向直接后继和直接前驱。所以,从双向链表中的任意一个结点开始,都可以很方便地访问它的前驱结点和后继结点。

图示:


代码如下:

DoubleList.h

#ifndef DOUBLELIST_H_
#define DOUBLELIST_H_

typedef char ElemType;
typedef struct DNode
{
	ElemType data;
	struct DNode *prior;//指向前驱结点
	struct DNode *next;//指向后继结点
}DLinkList;//双向链表类型定义

/*初始化双向链表*/
void InitList(DLinkList *&L);//&L是以应用方式调用L,可以修改指针L

/*释放双向链表*/
void DestroyList(DLinkList *&L);

/*判断双向链表是否为空*/
int ListEmpty(DLinkList *L);

/*返回双向链表结点的个数*/
int ListLength(DLinkList *L);

/*打印双向链表*/
void PrintList(DLinkList *L);

/*获取双向链表中第i个元素*/
int GetElem(DLinkList *L,int i,ElemType &e);

/*在双向链表中查找元素e,返回它的序号*/
int LocateElem(DLinkList *L,ElemType e);

/*在双向链表的第i个位置插入元素e*/
int InsertList(DLinkList *&L,int i,ElemType e);//&L是以应用方式调用L,可以修改指针L

/*在双向链表中删除第i个元素*/
int ListDelete(DLinkList *&L,int i,ElemType &e);//&L是以应用方式调用L,可以修改指针L

#endif

DoubleList.cpp

#include <iostream>
#include <malloc.h>
#include "DoubleList.h"

using namespace std;
/*初始化双向链表*/
void InitList(DLinkList *&L)//&L是以应用方式调用L,可以修改指针L
{
	L=(DLinkList*)malloc(sizeof(DLinkList));//创建头结点
	L->next=NULL;
	L->prior=NULL;
}

/*释放双向链表*/
void DestroyList(DLinkList *&L)
{
	DLinkList *p=L,*q=L->next;
	while(q!=NULL)
	{
		free(p);
		p=q;
		q=p->next;
	}
	free(p);	
}

/*判断双向链表是否为空*/
int ListEmpty(DLinkList *L)
{
	return (L->next==NULL);
}

/*返回双向链表结点的个数*/
int ListLength(DLinkList *L)
{
	DLinkList *p=L->next;//p指向第一结点
	int n=0;
	while(p!=NULL)
	{
		n++;
		p=p->next;
	}
	return n;
}

/*打印双向链表*/
void PrintList(DLinkList *L)
{
	DLinkList *p=L->next;
	while(p!=NULL)
	{
		cout<<p->data<<'\t';
		p=p->next;
	}
	cout<<endl;
}

/*获取双向链表中第i个元素*/
int GetElem(DLinkList *L,int i,ElemType &e)
{
	DLinkList *p=L->next;
	int j=0;
	while(p!=NULL&&j<i)
	{
		p=p->next;
		j++;
	}
	if(p==NULL)
		return 0;
	else
	{
		e=p->data;
		return 1;
	}
}

/*在双向链表中查找元素e,返回它的序号*/
int LocateElem(DLinkList *L,ElemType e)
{
	DLinkList *p=L->next;
	int i=0;
	while(p!=NULL&&p->data!=e)
	{
		p=p->next;
		i++;
	}
	if(p==NULL)
		return 0;
	else
	{
		return i;
	}
}

/*在双向链表的第i个位置插入元素e*/
int InsertList(DLinkList *&L,int i,ElemType e)//&L是以应用方式调用L,可以修改指针L
{
	DLinkList *p=L,*q;
	int j=0;
	while(p!=NULL&&j<i)
	{
		p=p->next;
		j++;
	}
	if(p==NULL)
		return 0;
	else
	{
		q=(DLinkList*)malloc(sizeof(DLinkList));
		q->data=e;
		q->next=p->next;
		if(p->next!=NULL)
			p->next->prior=q;
		q->prior=p;
		p->next=q;
		return 1;
	}
}

/*在双向链表中删除第i个元素*/
int ListDelete(DLinkList *&L,int i,ElemType &e)//&L是以应用方式调用L,可以修改指针L
{
	DLinkList *p=L->next,*q;
	int j=0;
	while(j<i-1&&p!=NULL)
	{
		p=p->next;
		j++;
	}
	if(p==NULL)
		return 0;
	else
	{
		q=p->next;//q指向被删除的结点
		if(q==NULL)
			return 0;//不存在第i个结点
		e=q->data;
		p->next=q->next;//删除结点q
		if(p->next!=NULL)//删除的是最后一个结点
			p->next->prior=p;
		free(q);
		return 1;
	}	
}



main.cpp

#include<iostream>
#include<malloc.h>
#include"DoubleList.h"

using namespace std;
int main()
{
	DLinkList *L;
	ElemType e;
	cout<<"(1)初始化双向链表L"<<endl;
	InitList(L);

	cout<<"(2)依次采用尾插入法插入a,b,c,d,e,g,h元素"<<endl;
	InsertList(L,0,'a');
	InsertList(L,1,'b');
	InsertList(L,2,'c');
	InsertList(L,3,'d');
	InsertList(L,4,'e');
	InsertList(L,5,'g');
	InsertList(L,6,'h');

	cout<<"(3)输出双向链表"<<endl;
	PrintList(L);

	cout<<"(4)双向链表的长度Length="<<ListLength(L)<<endl;
	cout<<"(5)判断双向链表是否为空"<<endl;
	if (ListEmpty(L))
	{
		cout<<"双向链表为空"<<endl;
	} 
	else
	{
		cout<<"双向链表不为空"<<endl;
	}
	GetElem(L,4,e);
	cout<<"(6)双向表L的第4个元素为="<<e<<endl;

	cout<<"(7)双向表中元素g的位置i="<<LocateElem(L,'g')<<endl;

	cout<<"(8)在第4个元素位置上插入f元素"<<endl;
	InsertList(L,4,'f');
	cout<<"(9)输出双向表"<<endl;
	PrintList(L);

	cout<<"(10)删除双向表中的第3个元素"<<endl;
	ListDelete(L,3,e);																	
	cout<<"(11)输出双向表L"<<endl;
	PrintList(L);

	cout<<"(12)再在头结点处插入新结点"<<endl;
	InsertList(L,0,'m');
	cout<<"(13)输出双向表L"<<endl;
	PrintList(L);

	cout<<"(14)释放双向表L"<<endl;
	DestroyList(L);
	return 0;
}

结果如下:



  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值